52 const Boundary& orig,
const Boundary& conv,
double scale,
double rot,
bool inverse,
bool flatten):
55 myProjection(nullptr),
56 myInverseProjection(nullptr),
57 myGeoProjection(nullptr),
63 myProjectionMethod(NONE),
64 myUseInverseProjection(inverse),
67 myConvBoundary(conv) {
70 }
else if (proj ==
"-") {
72 }
else if (proj ==
"UTM") {
74 }
else if (proj ==
"DHDN") {
76 }
else if (proj ==
"DHDN_UTM") {
81 myProjection = pj_init_plus(proj.c_str());
82 if (myProjection ==
nullptr) {
93 if (myProjection !=
nullptr) {
94 pj_free(myProjection);
96 if (myInverseProjection !=
nullptr) {
97 pj_free(myInverseProjection);
99 if (myGeoProjection !=
nullptr) {
100 pj_free(myInverseProjection);
134 if (myProjection !=
nullptr) {
135 pj_free(myProjection);
136 myProjection =
nullptr;
138 if (myInverseProjection !=
nullptr) {
139 pj_free(myInverseProjection);
140 myInverseProjection =
nullptr;
142 if (myGeoProjection !=
nullptr) {
143 pj_free(myGeoProjection);
144 myGeoProjection =
nullptr;
146 if (orig.myProjection !=
nullptr) {
149 if (orig.myInverseProjection !=
nullptr) {
150 myInverseProjection = pj_init_plus(pj_get_def(orig.myInverseProjection, 0));
152 if (orig.myGeoProjection !=
nullptr) {
153 myGeoProjection = pj_init_plus(pj_get_def(orig.myGeoProjection, 0));
162 std::string proj =
"!";
163 double scale = oc.
getFloat(
"proj.scale");
164 double rot = oc.
getFloat(
"proj.rotate");
166 bool inverse = oc.
exists(
"proj.inverse") && oc.
getBool(
"proj.inverse");
167 bool flatten = oc.
exists(
"flatten") && oc.
getBool(
"flatten");
169 if (oc.
getBool(
"simple-projection")) {
175 WRITE_ERROR(
"Inverse projection works only with explicit proj parameters.");
179 if (numProjections > 1) {
180 WRITE_ERROR(
"The projection method needs to be uniquely defined.");
186 }
else if (oc.
getBool(
"proj.dhdn")) {
188 }
else if (oc.
getBool(
"proj.dhdnutm")) {
202 const Boundary& conv,
double scale) {
213 oc.
addSynonyme(
"simple-projection",
"proj.simple",
true);
214 oc.
addDescription(
"simple-projection",
"Projection",
"Uses a simple method for projection");
217 oc.
addDescription(
"proj.scale",
"Projection",
"Scaling factor for input coordinates");
220 oc.
addDescription(
"proj.rotate",
"Projection",
"Rotation (clockwise degrees) for input coordinates");
224 oc.
addDescription(
"proj.utm",
"Projection",
"Determine the UTM zone (for a universal transversal mercator projection based on the WGS84 ellipsoid)");
227 oc.
addDescription(
"proj.dhdn",
"Projection",
"Determine the DHDN zone (for a transversal mercator projection based on the bessel ellipsoid, \"Gauss-Krueger\")");
230 oc.
addDescription(
"proj",
"Projection",
"Uses STR as proj.4 definition for projection");
233 oc.
addDescription(
"proj.inverse",
"Projection",
"Inverses projection");
236 oc.
addDescription(
"proj.dhdnutm",
"Projection",
"Convert from Gauss-Krueger to UTM");
260 const double y = cartesian.
y() / 111136.;
261 const double x = cartesian.
x() / 111320. / cos(
DEG2RAD(y));
269 p = pj_inv(p, myProjection);
273 cartesian.
set((
double) p.u, (
double) p.v);
280 if (includeInBoundary) {
285 if (myProjection ==
nullptr) {
289 int zone = (int)((x - 500000.) / 1000000.);
290 if (zone < 1 || zone > 5) {
295 " +k=1 +x_0=" +
toString(zone * 1000000 + 500000) +
296 " +y_0=0 +ellps=bessel +datum=potsdam +units=m +no_defs";
297 myInverseProjection = pj_init_plus(
myProjString.c_str());
298 myGeoProjection = pj_init_plus(
"+proj=latlong +datum=WGS84");
300 x = ((x - 500000.) / 1000000.) * 3;
304 int zone = (int)(x + 180) / 6 + 1;
306 " +ellps=WGS84 +datum=WGS84 +units=m +no_defs";
312 int zone = (int)(x / 3);
313 if (zone < 1 || zone > 5) {
318 " +k=1 +x_0=" +
toString(zone * 1000000 + 500000) +
319 " +y_0=0 +ellps=bessel +datum=potsdam +units=m +no_defs";
328 if (myInverseProjection !=
nullptr) {
331 if (pj_transform(myInverseProjection, myGeoProjection, 1, 1, &x, &y,
nullptr)) {
334 from.
set(
double(x * RAD_TO_DEG),
double(y * RAD_TO_DEG));
340 if (includeInBoundary) {
353 double y = x2 * mySin + y2 *
myCos;
359 if (x > 180.1 || x < -180.1) {
363 if (y > 90.1 || y < -90.1) {
368 if (myProjection !=
nullptr) {
370 p.u = x * DEG_TO_RAD;
371 p.v = y * DEG_TO_RAD;
372 p = pj_fwd(p, myProjection);
379 x *= 111320. * cos(
DEG2RAD(y));
384 if (x > std::numeric_limits<double>::max() ||
385 y > std::numeric_limits<double>::max()) {
void doRegister(const std::string &name, Option *v)
Adds an option under the given name.
OutputDevice & writeAttr(const SumoXMLAttr attr, const T &val)
writes a named attribute
static void writeLocation(OutputDevice &into)
writes the location element
static GeoConvHelper myProcessing
coordinate transformation to use for input conversion and processing
~GeoConvHelper()
Destructor.
const Boundary & getConvBoundary() const
Returns the converted boundary.
void add(const Position &pos)
Adds the given position to this one.
Position myOffset
The offset to apply.
static void computeFinal(bool lefthand=false)
compute the location attributes which will be used for output based on the loaded location data...
bool x2cartesian(Position &from, bool includeInBoundary=true)
Converts the given coordinate into a cartesian and optionally update myConvBoundary.
double y() const
Returns the y-position.
bool usingGeoProjection() const
Returns whether a transformation from geo to metric coordinates will be performed.
void moveby(double x, double y, double z=0)
Moves the boundary by the given amount.
double mySin
The rotation to apply to geo-coordinates.
Boundary myOrigBoundary
The boundary before conversion (x2cartesian)
static void setLoaded(const GeoConvHelper &loaded)
sets the coordinate transformation loaded from a location element
double x() const
Returns the x-position.
void setPrecision(int precision=gPrecision)
Sets the precison or resets it to default.
const Boundary & getOrigBoundary() const
Returns the original boundary.
bool myFlatten
whether to discard z-data
static GeoConvHelper myLoaded
coordinate transformation loaded from a location element
bool getBool(const std::string &name) const
Returns the boolean-value of the named option (only for Option_Bool)
const std::string & getProjString() const
Returns the original projection definition.
static void resetLoaded()
resets loaded location elements
bool isDefault(const std::string &name) const
Returns the information whether the named option has still the default value.
void set(double x, double y)
set positions x and y
bool myUseInverseProjection
Information whether inverse projection shall be used.
void moveConvertedBy(double x, double y)
Shifts the converted boundary by the given amounts.
A class that stores a 2D geometrical boundary.
#define WRITE_WARNING(msg)
void addSynonyme(const std::string &name1, const std::string &name2, bool isDeprecated=false)
Adds a synonyme for an options name (any order)
void cartesian2geo(Position &cartesian) const
Converts the given cartesian (shifted) position to its geo (lat/long) representation.
double myGeoScale
The scaling to apply to geo-coordinates.
static methods for processing the coordinates conversion for the current net
std::string toString(const T &t, std::streamsize accuracy=gPrecision)
static GeoConvHelper myFinal
coordinate transformation to use for writing the location element and for tracking the original coord...
A point in 2D or 3D with translation and scaling methods.
ProjectionMethod myProjectionMethod
Information whether no projection shall be done.
std::string myProjString
A proj options string describing the proj.4-projection to use.
std::string getString(const std::string &name) const
Returns the string-value of the named option (only for Option_String)
bool exists(const std::string &name) const
Returns the information whether the named option is known.
static bool init(OptionsCont &oc)
Initialises the processing and the final instance using the given options.
void addOptionSubTopic(const std::string &topic)
Adds an option subtopic.
static void addProjectionOptions(OptionsCont &oc)
Adds projection options to the given container.
GeoConvHelper(OptionsCont &oc)
Constructor based on the stored options.
double getFloat(const std::string &name) const
Returns the double-value of the named option (only for Option_Float)
Boundary myConvBoundary
The boundary after conversion (x2cartesian)
static int myNumLoaded
the numer of coordinate transformations loaded from location elements
bool operator==(const GeoConvHelper &o) const
void flipY()
flips ymin and ymax
A storage for options typed value containers)
bool usingInverseGeoProjection() const
Returns the information whether an inverse transformation will happen.
const Position getOffsetBase() const
Returns the network base.
Static storage of an output device and its base (abstract) implementation.
bool x2cartesian_const(Position &from) const
Converts the given coordinate into a cartesian using the previous initialisation. ...
bool closeTag(const std::string &comment="")
Closes the most recently opened tag and optionally adds a comment.
void mul(double val)
Multiplies both positions with the given value.
const Position getOffset() const
Returns the network offset.
void addDescription(const std::string &name, const std::string &subtopic, const std::string &description)
Adds a description for an option.
void add(double x, double y, double z=0)
Makes the boundary include the given coordinate.
OutputDevice & openTag(const std::string &xmlElement)
Opens an XML tag.
void lf()
writes a line feed if applicable
GeoConvHelper & operator=(const GeoConvHelper &)
make assignment operator private
void setz(double z)
set position z
void sub(double dx, double dy)
Substracts the given position from this one.