Opened 7 years ago

Last modified 5 years ago

#434 reopened defect

Projection handling problems (defs folder and not passing wkt for parsing)

Reported by: zspitzer Owned by: madair
Priority: P2 Milestone: 2.2
Component: MapGuide Version: 2.2 - RC1
Severity: Major Keywords:
Cc: Browser: All
External ID: Operating System: All
state: New

Description

  1. With 2.2 RC2, the standard template uses the fusion/lib/def directory while the other templates use the template/def directory.

The problem relates to the single file version using lib/defs, while the uncombined version uses template/defs

  1. MapGuide provides a WKT projection, but it's not being passed to Proj4js for parsing.

i.e. the map I'm currently working with has this projection in the map definition

<CoordinateSystem?>PROJCS["MGA-55",GEOGCS["LL-GDA94",DATUM["GDA94",SPHEROID["GRS1980",6378137.000,298.25722210]],PRIMEM["Greenwich",0],UNIT["Degree",0.017453292519943295]],PROJECTIONTransverse_Mercator?,PARAMETER["false_easting",500000.000],PARAMETER["false_northing",10000000.000],PARAMETER["scale_factor",0.999600000000],PARAMETER["central_meridian",147.00000000000000],PARAMETER["latitude_of_origin",0.00000000000000],UNIT["Meter",1.00000000000000]]</CoordinateSystem?>

looking at the proj4js-combined.js file around line 486, I see the following code

check to see if this is a WKT string

if ((srsCode.indexOf('GEOGCS') >= 0)
(srsCode.indexOf('GEOCCS') >= 0) (srsCode.indexOf('PROJCS') >= 0)

(srsCode.indexOf('LOCAL_CS') >= 0)) {

this.parseWKT(srsCode); this.datum = new Proj4js.datum(this); this.loadProjCode(this.projName); return;

}

The SRS being passed is only the EPSG:28355 string, as opposed to the definition from the map

hacking around, If I change the line in LoadMap?.php line 114

$mapObj->wkt = $srs; $mapObj->epsg = $epsgCode;

to

$mapObj->wkt = $srs; $mapObj->epsg = $srs;

Result: no external projection requests as proj4js parsing of PROJCS is triggered.

Attachments (2)

useWKTFirst.patch (1.6 KB) - added by madair 7 years ago.
ticket434.patch (1.8 KB) - added by zhanga 5 years ago.
There is a case that the wkt string is invalid or outdated. The property wktProj.proj.readyToUse is false in this case. We need to check the value of readyToUse after wktProj object is constructed.

Download all attachments as: .zip

Change History (11)

comment:1 Changed 7 years ago by madair

The EPSG code in LoadMap?.php should in theory hold a valid EPSG code, if it can find one, so I would prefer that the change in logic happen further downstream like at lines 308-317 of MapGuide.js where the epsg code and wkt are parsed. It might make sense to change the logic there so that it checks for a valid WKT before checking for an epsg code.

What is the value of the EPSG code being set to in your case?

comment:2 Changed 7 years ago by zspitzer

Load map is returning epsg as 28355

which loads http://spatialreference.org/ref/epsg/28355/proj4js/ Proj4js.defsEPSG:28355? = "+proj=utm +zone=55 +south +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m +no_defs";

If it helps, I can send you a sqlite mgp of this map via email

Changed 7 years ago by madair

Attachment: useWKTFirst.patch added

comment:3 Changed 7 years ago by madair

Zac, Can you test with the attached patch please? The change is so that MapGuide layers will use the WKT text first, any EPSG code returned second, and a LOCAL CS if there is no CS information supplied at all. It also adds a n OpenLayers unit-per-inch value for "Degree" units

comment:4 Changed 7 years ago by jng

I can confirm that the fusion bundled with RC3 with this patch applied does not fire off requests to spatialreference.org

comment:5 Changed 7 years ago by madair

Resolution: fixed
Status: newclosed

fixed in trunk and 2.2 at rev 2350

comment:6 Changed 7 years ago by jng

There is one small problem with this solution. Though the OpenLayers.Projection is correctly constructed from the WKT, it will still carry the EPSG code of 4326, and it is the setting of the EPSG code on the OpenLayers.Projection object that makes it fire off a spatialreference.org request *regardless* of whether it was created from the WKT or not.

What should ideally happen is if wkt is found, create the OpenLayers.Projection object from it, but also set the epsg code if there is one, but have the logic in OpenLayers.Projection modified to *not* fire off the request to spatialreference.org if the object was created in this fashion.

comment:7 Changed 5 years ago by wuma

Resolution: fixed
Status: closedreopened

comment:8 Changed 5 years ago by wuma

Hi Mike,

After the enhancement, how to deal with the projection CS which doesn't have definition in Proj4js built-in defs? E.g. I have a projection CS as below:

PROJCS["CH1903Plus_1.LV95/01",
  GEOGCS[
    "CH1903Plus_1.LL",
      DATUM["CH1903Plus_1",
        SPHEROID["BESSEL",6377397.155,299.15281535],
        TOWGS84[674.3740,15.0560,405.3460,0.000000,0.000000,0.000000,0.00000000]],
      PRIMEM["Greenwich",0],
      UNIT["Degree",0.017453292519943295]],
  PROJECTION["Swiss_Oblique_Cylindrical"],
  PARAMETER["false_easting",2600000.000],
  PARAMETER["false_northing",1200000.000],
  PARAMETER["latitude_of_origin",46.95240555555556],
  PARAMETER["central_meridian",7.43958333333333],
  UNIT["Meter",1.00000000000000]]

The projection PROJECTION["Swiss_Oblique_Cylindrical"] is not defined in Proj4js.wktProjections, then the projName will be evaluated as undefined which means it's not possible to load the projection def from an url. What's your suggestion to support this kind of projection CS?

Thanks, Mars

comment:9 Changed 5 years ago by jng

From my experience, driving things through WKTs is unreliable (problem with proj4js. I wish we could just tap into cs-map from javascript! Problem would be solved!)

If we can do things via EPSG and supply the required proj4 string where needed to Proj4js.defs (hence the idea of #535 to avoid external lookups), things are usually better.

So in this case, mapagent ConvertWktToEpsgCode? says epsg is 2056

spatialreference.org says the proj4 string for this is:

+proj=somerc +lat_0=46.95240555555556 +lon_0=7.439583333333333 +k_0=1 +x_0=2600000 +y_0=1200000 +ellps=bessel +towgs84=674.374,15.056,405.346,0,0,0,0 +units=m +no_defs

So I'm guessing you'd have to do this somewhere in the fusion initialization process (or if #535 is implemented, as an CustomProjections? widget extension property):

Proj4js.defs["EPSG:2056"] = "+proj=somerc +lat_0=46.95240555555556 +lon_0=7.439583333333333 +k_0=1 +x_0=2600000 +y_0=1200000 +ellps=bessel +towgs84=674.374,15.056,405.346,0,0,0,0 +units=m +no_defs"

We could probably construct a csmap to proj4 lookup list to do this seamlessly. LoadMap?.php would just consult this lookup list to setup the correct OpenLayers.Projection and construct the required Proj4js.defs entry if required.

Changed 5 years ago by zhanga

Attachment: ticket434.patch added

There is a case that the wkt string is invalid or outdated. The property wktProj.proj.readyToUse is false in this case. We need to check the value of readyToUse after wktProj object is constructed.

Note: See TracTickets for help on using tickets.