diff --git a/simgear/canvas/elements/CanvasMap.cxx b/simgear/canvas/elements/CanvasMap.cxx index a7c43a51..ca97c4f7 100644 --- a/simgear/canvas/elements/CanvasMap.cxx +++ b/simgear/canvas/elements/CanvasMap.cxx @@ -97,17 +97,26 @@ namespace canvas || (!geo_node->isDirty() && !_projection_dirty) ) continue; - GeoCoord lat = parseGeoCoord(geo_node->getLat()); - if( lat.type != GeoCoord::LATITUDE ) - continue; - - GeoCoord lon = parseGeoCoord(geo_node->getLon()); - if( lon.type != GeoCoord::LONGITUDE ) - continue; - - Projection::ScreenPosition pos = - _projection->worldToScreen(lat.value, lon.value); - + double latD = -9999.0, lonD = -9999.0; + if (geo_node->isDirty()) { + GeoCoord lat = parseGeoCoord(geo_node->getLat()); + if( lat.type != GeoCoord::LATITUDE ) + continue; + + GeoCoord lon = parseGeoCoord(geo_node->getLon()); + if( lon.type != GeoCoord::LONGITUDE ) + continue; + + // save the parsed values so we can re-use them if only projection + // is changed (very common case for moving vehicle) + latD = lat.value; + lonD = lon.value; + geo_node->setCachedLatLon(std::make_pair(latD, lonD)); + } else { + std::tie(latD, lonD) = geo_node->getCachedLatLon(); + } + + Projection::ScreenPosition pos = _projection->worldToScreen(latD, lonD); geo_node->setScreenPos(pos.x, pos.y); // geo_node->print(); diff --git a/simgear/canvas/elements/map/geo_node_pair.hxx b/simgear/canvas/elements/map/geo_node_pair.hxx index 4733238b..aa01aa91 100644 --- a/simgear/canvas/elements/map/geo_node_pair.hxx +++ b/simgear/canvas/elements/map/geo_node_pair.hxx @@ -99,6 +99,12 @@ namespace canvas return _node_lon ? _node_lon->getStringValue() : ""; } + void setCachedLatLon(const std::pair& latLon) + { _cachedLatLon = latLon; } + + std::pair getCachedLatLon() + { return _cachedLatLon; } + void setTargetName(const std::string& name) { _target_name = name; @@ -138,6 +144,7 @@ namespace canvas std::string _target_name; SGPropertyNode_ptr _xNode, _yNode; + std::pair _cachedLatLon; };