Hi,
Background: Working in ArcGIS Runtime for QT version 100.8 in QT version 5.14 on an Ubuntu system running release 19.10.
I've got a KML GroundOverlay graphic whose position I'd like to update in real-time. The graphic is rendered just fine initially, but any subsequent calls to functions on the KmlGroundOverlay don't seem to have an effect. As an example, here's a bit of code:
Considering the variables:
Esri::ArcGISRuntime::KmlGroundOverlay * m_groundOverlay; Esri::ArcGISRuntime::KmlDataset *m_kdata; Esri::ArcGISRuntime::KmlLayer *m_klayer; Esri::ArcGISRuntime::Map *m_map;
In the "before" code - before the KML is called:
m_map(new Map(Basemap::topographicVector(this), this));
Setting up the KML Ground Overlay:
const Envelope env(-.001, 0.001, .001, 0.00, SpatialReference::wgs84()); KmlIcon * kmlIcon = new KmlIcon(QUrl("/home/bcrist/hundySquare.png")); // "hundySquare.png" is a red square shaped image file // Create Overlay m_groundOverlay = new Esri::ArcGISRuntime::KmlGroundOverlay(env, kmlIcon, this); // Create Dataset m_kdata = new Esri::ArcGISRuntime::KmlDataset(m_groundOverlay, this); // Create Layer m_klayer = new Esri::ArcGISRuntime::KmlLayer(m_kdata, this); m_map->operationalLayers()->append(m_klayer);
Subsequently trying to just spin the layer around via a timer-called separate function (for testing purposes, obviously):
m_groundOverlay->setRotation(m_groundOverlay->rotation() + 1); if (m_groundOverlay->rotation() > 360) { m_groundOverlay->setRotation(0); }
I've assembled the "EditKmlGroundOverlay" sample from the arcgis-runtime-samples-qt repo on Git and altered it do perform the rotation above, and it works fine. The only difference I can figure out is that the EditKmlGroundOverlay sample uses a scene view instead of a map view.
Is this a limitation of Map Views or am I doing something wrong or missing something?
Hey Brian-
Thanks for your email. We are wrapping up 100.9 release right now, so it is a bit hectic.
I passed your information onto our senior product managers for their consideration. Hopefully we can either get the KML Ground Overlay 2D issue fixed or Image Overlay in 2D implemented, but that timeline is unknown. What I do know is 100.9 is going to be released in a week or so, but neither of these will be in that release.
For the time being, would it be an option to use 3D instead of 2D and orient the camera in a top down manner so it looks 2D?
Hi Lucas,
I initially thought doing a "top-down" 3-d look would be the best option, but we need to display grid lines; the program manager has indicated losing grid-lines is a non-starter.
The work-around I'm using feels very clumsy, but maybe it's the best I can do:
Regards,
Brian
Hi Brian-
Maybe MapView::unitsPerDIP could get you what you need - https://developersdev.arcgis.com/qt/latest/cpp/api-reference/esri-arcgisruntime-mapview.html#unitsPe...
We added this API so users could build a scalebar, which conceptually is very similar to the need you have - to tell how many real-world units are in one device independent pixel. Real-world units will be in whatever the 0th layer in the map is, so if you are using web mercator basemap, it will be meters.
Hi Lucas,
This is where my ignorance of GIS comes into play. So the map I'm using is a Basemap::TopographicVector and the mapView's spatial reference is WKID 3857, who's unit is a meter.
When I use unitsPerDip (which I tried quite a while ago when I was first wrestling with this) - when I render my 100 meter square at 0,0 everything is great. But when I render it in Vermont (-72.9927854, 44.4050029 in spatial reference Wkid 4326), the size is reduced.
I understand this has to do with the projection somehow, but I do not understand how.
I came up with a pretty hacky way to solve this which seems to be working:
When the zoom level changes, I obtain Points from two adjoining pixels in the middle of the mapView using screenToLocation and using the GeometryEngine to calculate the meters between these two points. This gives me a "pixels to meters" which seems to calculate the size of my 100x100 square pretty accurately wherever it is in the world.
I then divide that value by the ratio of the mapView's scale to the Map's scale.
However, I think this is probably a little more resource intensive than it should be, and it definitely feels like a hack. Is there any way you can either email me or clarify on this thread how I take the UnitsPerDip and project them properly at various latitudes?
Thanks so much,
Brian
It's probably important to note that I'm using an overlay whose setScaleSymbols flag is set to true also. I think that's an important element to my code above functioning properly.