Skip to content

Commit

Permalink
Georeferencing: Save realization CRS to file
Browse files Browse the repository at this point in the history
Instead of saving _that_ the map was developed with a recent
realization of WGS84 for its geographic CRS, save the _spec_ of the
geographic CRS itself.
  • Loading branch information
pkturner committed Feb 17, 2024
1 parent addecfe commit 68c70f5
Show file tree
Hide file tree
Showing 8 changed files with 44 additions and 21 deletions.
39 changes: 27 additions & 12 deletions src/core/georeferencing.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ namespace literal
static const QLatin1String ref_point_deg("ref_point_deg");
static const QLatin1String projected_crs("projected_crs");
static const QLatin1String geographic_crs("geographic_crs");
static const QLatin1String is_realization("is_realization");
static const QLatin1String realization_spec("realization_spec");
static const QLatin1String spec("spec");
static const QLatin1String parameter("parameter");

Expand All @@ -88,8 +88,6 @@ namespace literal

static const QLatin1String proj_4("PROJ.4");
static const QLatin1String geographic_coordinates("Geographic coordinates");
static const QLatin1String f("false");
static const QLatin1String t("true");
}


Expand Down Expand Up @@ -521,7 +519,7 @@ Georeferencing::Georeferencing()
convergence(0.0),
map_ref_point(0, 0),
projected_ref_point(0, 0),
is_realization(true),
realization_crs_spec(gnss_crs_spec),
explicit_realization(false)
{
static ProjSetup run_once;
Expand All @@ -547,7 +545,7 @@ Georeferencing::Georeferencing(const Georeferencing& other)
projected_crs_id(other.projected_crs_id),
projected_crs_spec(other.projected_crs_spec),
projected_crs_parameters(other.projected_crs_parameters),
is_realization(other.is_realization),
realization_crs_spec(other.realization_crs_spec),
explicit_realization(other.explicit_realization),
proj_transform(projected_crs_spec, gnss_crs_spec),
geographic_ref_point(other.geographic_ref_point)
Expand Down Expand Up @@ -579,7 +577,7 @@ Georeferencing& Georeferencing::operator=(const Georeferencing& other)
projected_crs_id = other.projected_crs_id;
projected_crs_spec = other.projected_crs_spec;
projected_crs_parameters = other.projected_crs_parameters;
is_realization = other.is_realization;
realization_crs_spec = other.realization_crs_spec;
explicit_realization = other.explicit_realization;
proj_transform = ProjTransform(other.projected_crs_spec, gnss_crs_spec);
geographic_ref_point = other.geographic_ref_point;
Expand Down Expand Up @@ -688,8 +686,8 @@ void Georeferencing::load(QXmlStreamReader& xml, bool load_scale_only)
else if (xml.name() == literal::geographic_crs)
{
XmlElementReader crs_element(xml);
explicit_realization = crs_element.hasAttribute(literal::is_realization);
is_realization = explicit_realization && crs_element.attribute<bool>(literal::is_realization);
explicit_realization = false;
realization_crs_spec = QString();
while (xml.readNextStartElement())
{
XmlElementReader current_element(xml);
Expand All @@ -702,6 +700,16 @@ void Georeferencing::load(QXmlStreamReader& xml, bool load_scale_only)
if (Georeferencing::ballpark_geographic_crs_spec != geographic_crs_spec)
throw FileFormatException(tr("Unsupported geographic CRS specification: %1").arg(geographic_crs_spec));
}
else if (xml.name() == literal::realization_spec)
{
explicit_realization = true;
QString language{};
if (current_element.hasAttribute(literal::language))
language = current_element.attribute<QString>(literal::language);
realization_crs_spec = xml.readElementText();
if (!realization_crs_spec.isEmpty() && language != literal::proj_4)
throw FileFormatException(tr("Unknown realization CRS specification language: %1").arg(language));
}
else if (xml.name() == literal::ref_point)
{
// Legacy, latitude/longitude in radiant
Expand Down Expand Up @@ -806,13 +814,20 @@ void Georeferencing::save(QXmlStreamWriter& xml) const
{
XmlElementWriter crs_element(xml, literal::geographic_crs);
crs_element.writeAttribute(literal::id, literal::geographic_coordinates);
if (explicit_realization)
crs_element.writeAttribute(literal::is_realization, is_realization ? literal::t : literal::f);
{
XmlElementWriter spec_element(xml, literal::spec);
spec_element.writeAttribute(literal::language, literal::proj_4);
xml.writeCharacters(ballpark_geographic_crs_spec);
}
if (explicit_realization)
{
XmlElementWriter realization_element(xml, literal::realization_spec);
if (!realization_crs_spec.isEmpty())
{
realization_element.writeAttribute(literal::language, literal::proj_4);
xml.writeCharacters(realization_crs_spec);
}
}
if (XMLFileFormat::active_version < 6)
{
// Legacy compatibility
Expand Down Expand Up @@ -1192,9 +1207,9 @@ bool Georeferencing::setDatumBallpark(bool ballpark)
// Default return value if no change is necessary
bool ok = (getState() == Geospatial);

if (is_realization != !ballpark)
if (realization_crs_spec.isEmpty() != ballpark)
{
is_realization = !ballpark;
realization_crs_spec = ballpark ? QString() : gnss_crs_spec;
proj_transform = ProjTransform(projected_crs_spec, getGeographicCRSSpec());
ok = proj_transform.isValid();
if (ok)
Expand Down
8 changes: 5 additions & 3 deletions src/core/georeferencing.h
Original file line number Diff line number Diff line change
Expand Up @@ -446,14 +446,16 @@ friend QDebug operator<<(QDebug dbg, const Georeferencing& georef);
* and also the source CRS when applicable.
* @return a PROJ specification of the geographic CRS
*/
const QString& getGeographicCRSSpec() const { return is_realization ? gnss_crs_spec : ballpark_geographic_crs_spec; }
const QString& getGeographicCRSSpec() const { return realization_crs_spec.isEmpty()
? ballpark_geographic_crs_spec
: realization_crs_spec; }

/**
* Returns whether transformations use loose accuracy around the WGS84
* datum for explicitly requested compatibility with older releases of Mapper.
* @return true if transformations are set compatible, false otherwise
*/
bool isDatumBallpark() const { return explicit_realization && !is_realization; }
bool isDatumBallpark() const { return explicit_realization && realization_crs_spec.isEmpty(); }

/**
* Sets the coordinate reference system (CRS) of the geographical coordinates,
Expand Down Expand Up @@ -721,7 +723,7 @@ friend QDebug operator<<(QDebug dbg, const Georeferencing& georef);
QString projected_crs_spec;
std::vector< QString > projected_crs_parameters;

bool is_realization;
QString realization_crs_spec;
bool explicit_realization;

ProjTransform proj_transform;
Expand Down
3 changes: 2 additions & 1 deletion test/data/templates/geotiff.xmap
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,9 @@
<parameter>2180</parameter>
<ref_point x="649800" y="392500"/>
</projected_crs>
<geographic_crs id="Geographic coordinates" is_realization="true">
<geographic_crs id="Geographic coordinates">
<spec language="PROJ.4">+proj=latlong +datum=WGS84</spec>
<realization_spec language="PROJ.4">EPSG:9057</realization_spec>
<ref_point_deg lat="51.3793253" lon="21.15318339"/>
</geographic_crs>
</georeferencing>
Expand Down
3 changes: 2 additions & 1 deletion test/data/templates/ogr-template.xmap
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,9 @@
<parameter>2180</parameter>
<ref_point x="649800" y="392500"/>
</projected_crs>
<geographic_crs id="Geographic coordinates" is_realization="true">
<geographic_crs id="Geographic coordinates">
<spec language="PROJ.4">+proj=latlong +datum=WGS84</spec>
<realization_spec language="PROJ.4">EPSG:9057</realization_spec>
<ref_point_deg lat="51.3793253" lon="21.15318339"/>
</geographic_crs>
</georeferencing>
Expand Down
3 changes: 2 additions & 1 deletion test/data/templates/template-track-NA-ballpark-GDAL.xmap
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,9 @@
<parameter>6342</parameter>
<ref_point x="500000" y="4430000"/>
</projected_crs>
<geographic_crs id="Geographic coordinates" is_realization="false">
<geographic_crs id="Geographic coordinates">
<spec language="PROJ.4">+proj=latlong +datum=WGS84</spec>
<realization_spec/>
<ref_point_deg lat="40.02021349" lon="-105.00001013"/>
</geographic_crs>
</georeferencing>
Expand Down
3 changes: 2 additions & 1 deletion test/data/templates/template-track-NA.xmap
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,9 @@
<parameter>6342</parameter>
<ref_point x="500000" y="4430000"/>
</projected_crs>
<geographic_crs id="Geographic coordinates" is_realization="true">
<geographic_crs id="Geographic coordinates">
<spec language="PROJ.4">+proj=latlong +datum=WGS84</spec>
<realization_spec language="PROJ.4">EPSG:9057</realization_spec>
<ref_point_deg lat="40.02021349" lon="-105.00001013"/>
</geographic_crs>
</georeferencing>
Expand Down
3 changes: 2 additions & 1 deletion test/data/templates/template-track.xmap
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,9 @@
<parameter>2180</parameter>
<ref_point x="649800" y="392500"/>
</projected_crs>
<geographic_crs id="Geographic coordinates" is_realization="true">
<geographic_crs id="Geographic coordinates">
<spec language="PROJ.4">+proj=latlong +datum=WGS84</spec>
<realization_spec language="PROJ.4">EPSG:9057</realization_spec>
<ref_point_deg lat="51.3793253" lon="21.15318339"/>
</geographic_crs>
</georeferencing>
Expand Down
3 changes: 2 additions & 1 deletion test/data/templates/world-file.xmap
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,9 @@
<parameter>2180</parameter>
<ref_point x="649800" y="392500"/>
</projected_crs>
<geographic_crs id="Geographic coordinates" is_realization="true">
<geographic_crs id="Geographic coordinates">
<spec language="PROJ.4">+proj=latlong +datum=WGS84</spec>
<realization_spec language="PROJ.4">EPSG:9057</realization_spec>
<ref_point_deg lat="51.3793253" lon="21.15318339"/>
</geographic_crs>
</georeferencing>
Expand Down

0 comments on commit 68c70f5

Please sign in to comment.