Is there any function in ArcGIS Qt Runtime API deciding whether a given lat lon is on land or on sea? We want to take islands into consideration while performing this check.
Solved! Go to Solution.
Hi Fatma, thank you for your question! There's potentially a couple ways you can do this, but I came up with a quick solution by querying the World Countries feature layer's feature table.
I made a quick app that will tell you if the point you click on the map is either on land or sea. When the user clicks the map, it converts the screen position to map coordinates then queries the world countries feature table to see how many features intersect with the map coordinates. If one or more features intersect the map point, then we've clicked on land, otherwise the point is at sea. You could alternatively use the user's location or any other geometry for this query.
void LandOrSea::setupConnections()
{
PortalItem* worldCountriesItem = new PortalItem("ac80670eb213440ea5899bbf92a04998", this);
m_countriesLayer = new FeatureLayer(worldCountriesItem, 0, this);
connect(m_countriesLayer, &FeatureLayer::loadStatusChanged, this, [this](LoadStatus loadStatus)
{
if (loadStatus != LoadStatus::Loaded)
return;
m_countriesTable = m_countriesLayer->featureTable();
connect(m_countriesTable, &FeatureTable::queryFeatureCountCompleted, this, [](QUuid, int count)
{
qDebug() << (count > 0 ? "We've run aground" : "We're at sea!");
});
});
m_countriesLayer->load();
connect(m_mapView, &MapQuickView::mouseClicked, this, &LandOrSea::landOrSeaQuery);
}
void LandOrSea::landOrSeaQuery(QMouseEvent e)
{
if (!m_countriesTable || m_countriesTable->loadStatus() != LoadStatus::Loaded)
{
qDebug() << "Countries table is not loaded and is not ready to query";
return;
}
const Point mouseCoordinates = m_mapView->screenToLocation(e.pos().x(), e.pos().y());
QueryParameters queryParams;
queryParams.setGeometry(mouseCoordinates);
queryParams.setSpatialRelationship(SpatialRelationship::Intersects);
m_countriesTable->queryFeatureCount(queryParams);
}
I hope I've understood your question and I hope this helps. Let me know if there's anything else I can do for you, thank you!
Hi Fatma, thank you for your question! There's potentially a couple ways you can do this, but I came up with a quick solution by querying the World Countries feature layer's feature table.
I made a quick app that will tell you if the point you click on the map is either on land or sea. When the user clicks the map, it converts the screen position to map coordinates then queries the world countries feature table to see how many features intersect with the map coordinates. If one or more features intersect the map point, then we've clicked on land, otherwise the point is at sea. You could alternatively use the user's location or any other geometry for this query.
void LandOrSea::setupConnections()
{
PortalItem* worldCountriesItem = new PortalItem("ac80670eb213440ea5899bbf92a04998", this);
m_countriesLayer = new FeatureLayer(worldCountriesItem, 0, this);
connect(m_countriesLayer, &FeatureLayer::loadStatusChanged, this, [this](LoadStatus loadStatus)
{
if (loadStatus != LoadStatus::Loaded)
return;
m_countriesTable = m_countriesLayer->featureTable();
connect(m_countriesTable, &FeatureTable::queryFeatureCountCompleted, this, [](QUuid, int count)
{
qDebug() << (count > 0 ? "We've run aground" : "We're at sea!");
});
});
m_countriesLayer->load();
connect(m_mapView, &MapQuickView::mouseClicked, this, &LandOrSea::landOrSeaQuery);
}
void LandOrSea::landOrSeaQuery(QMouseEvent e)
{
if (!m_countriesTable || m_countriesTable->loadStatus() != LoadStatus::Loaded)
{
qDebug() << "Countries table is not loaded and is not ready to query";
return;
}
const Point mouseCoordinates = m_mapView->screenToLocation(e.pos().x(), e.pos().y());
QueryParameters queryParams;
queryParams.setGeometry(mouseCoordinates);
queryParams.setSpatialRelationship(SpatialRelationship::Intersects);
m_countriesTable->queryFeatureCount(queryParams);
}
I hope I've understood your question and I hope this helps. Let me know if there's anything else I can do for you, thank you!
Hi @Tanner_Yould ,
Thank you very much for this great answer! However our application will be installed on a mountain where there is no internet. Is there any way to download this "World Countries" feature so that we can make this check offline?
Hey, I'm glad I could be helpful! Depending on the size of the area you need, you may be able to take a specific area offline or download the whole feature service (or something similar) and create a mobile geodatabase to load onto your device. I'll link some sample code that demonstrates how to do that:
These two samples are two of many that we've written to cover most of the Runtime API and demonstrate use cases and best practices for using our API. Hopefully they can point you in the right direction, but don't hesitate to follow up with any additional questions.
Thanks!
Hi @Tanner_Yould , I really appreciate your help. I managed to generate the shapefile offline. However since it contains all countries, the land or sea check takes approximately 130 ms. Is there any way to reduce the shapefile or load only certain countries while creating FeatureTable?
There's a few things I'd try here:
Thank you very much @Tanner_Yould. I clipped the shapefile by using QGis application. After that, query time reduced to 2 ms.