jumpinjackie / mapguide-rest

REST Extension for MapGuide Open Source
GNU Lesser General Public License v2.1
26 stars 14 forks source link

transformto not working on Session Repository request #166

Open RenoSun opened 7 years ago

RenoSun commented 7 years ago

I was trying to request the redline layers geojson in LL84. The map coordinate system is in WGS84.Pseudomercator.

http://localhost/mapguide/rest/session/e6b168a0-156f-11e7-8000-b4b52f39b7bc_en_MTI3LjAuMC4x0AFC0AFB0AFA/Redline.LayerDefinition/features.geojson?includegeom=true&transformto=LL84

image

The result got from mapguide-rest was still in WGS84.Pseudomercator:

{ "type": "FeatureCollection", "features": [
{ "type": "Feature", "id": 1, "geometry": { "type": "Polygon", "coordinates": [[[-13853272.646002, 6333929.994099],[-13853272.574964, 6333946.3425344],[-13853272.26637, 6333949.3420209],[-13853271.378526, 6333952.2236666],[-13853269.945552, 6333954.876728],[-13853268.022518, 6333957.1992462],[-13853265.683328, 6333959.1019652],[-13853263.017879, 6333960.5117624],[-13853260.128605, 6333961.3744583],[-13853257.126543, 6333961.6568988],[-13853254.399352, 6333961.6449802],[-13853249.22075, 6333961.6223458],[-13853249.144144, 6333961.6220109],[-13853246.144761, 6333961.313357],[-13853243.263223, 6333960.4254924],[-13853240.610262, 6333958.9925361],[-13853238.287827, 6333957.0695541],[-13853236.385164, 6333954.7304431],[-13853236.222963, 6333954.4237827],[-13853235.879757, 6333954.1396075],[-13853233.977094, 6333951.8004953],[-13853232.567319, 6333949.1351416],[-13853231.704609, 6333946.2459713],[-13853231.422115, 6333943.2440099],[-13853231.506797, 6333923.7611102],[-13853231.815394, 6333920.7616246],[-13853232.703242, 6333917.8799804],[-13853234.136219, 6333915.2269211],[-13853236.059255, 6333912.9044054],[-13853238.398446, 6333911.0016892],[-13853241.063897, 6333909.5918951],[-13853243.953172, 6333908.7292024],[-13853246.955233, 6333908.4467648],[-13853249.192131, 6333908.4565429],[-13853252.191516, 6333908.7651958],[-13853255.073055, 6333909.6530597],[-13853257.726017, 6333911.0860157],[-13853260.048454, 6333913.0089978],[-13853261.951117, 6333915.3481093],[-13853261.954701, 6333915.3548844],[-13853263.212948, 6333915.7425762],[-13853265.865911, 6333917.1755297],[-13853268.188349, 6333919.0985096],[-13853270.091014, 6333921.4376191],[-13853271.500791, 6333924.1029704],[-13853272.363505, 6333926.9921389],[-13853272.646002, 6333929.994099]]] }, "properties": {"TEXT": null} }
]}
jumpinjackie commented 7 years ago

Something must be wrong with how the redline data store was set up.

Some things you need to check:

All 3 points above must be true for mapguide-rest to be able to create a WGS84.PseudoMercator to LL84 transform

RenoSun commented 7 years ago

Hi Jackie,

My spatial context association seems correct as following codes: `function createFeatureSourceJson() {

return {

    FeatureSourceParams: {

        File: {

            Provider: "OSGeo.SDF",

            FileName: "DrawingResults.sdf"

        },
        SpatialContext: {
            Name: "EPSG:3857",
            Description: "EPSG:3857",
            CoordinateSystem:'PROJCS["WGS 84 / Pseudo-Mercator",GEOGCS["WGS 84",DATUM["WGS_1984",SPHEROID["WGS 84",6378137,298.257223563,AUTHORITY["EPSG","7030"]],AUTHORITY["EPSG","6326"]],PRIMEM["Greenwich",0,AUTHORITY["EPSG","8901"]],UNIT["degree",0.0174532925199433,AUTHORITY["EPSG","9122"]],AUTHORITY["EPSG","4326"]],PROJECTION["Mercator_1SP"],PARAMETER["central_meridian",0],PARAMETER["scale_factor",1],PARAMETER["false_easting",0],PARAMETER["false_northing",0],UNIT["metre",1,AUTHORITY["EPSG","9001"]],AXIS["X",EAST],AXIS["Y",NORTH],EXTENSION["PROJ4","+proj=merc +a=6378137 +b=6378137 +lat_ts=0.0 +lon_0=0.0 +x_0=0.0 +y_0=0 +k=1.0 +units=m +nadgrids=@null +wktext  +no_defs"],AUTHORITY["EPSG","3857"]]',
            CoordinateSystemName:'PROJCS["WGS_1984_Web_Mercator_Auxiliary_Sphere",GEOGCS["GCS_WGS_1984",DATUM["D_WGS_1984",SPHEROID["WGS_1984",6378137.0,298.257223563]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Mercator_Auxiliary_Sphere"],PARAMETER["False_Easting",0.0],PARAMETER["False_Northing",0.0],PARAMETER["Central_Meridian",0.0],PARAMETER["Standard_Parallel_1",0.0],PARAMETER["Auxiliary_Sphere_Type",0.0],UNIT["Meter",1.0],AUTHORITY["EPSG",3857]]',
            CoordinateSystemWkt: 'PROJCS["WGS_1984_Web_Mercator_Auxiliary_Sphere",GEOGCS["GCS_WGS_1984",DATUM["D_WGS_1984",SPHEROID["WGS_1984",6378137.0,298.257223563]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Mercator_Auxiliary_Sphere"],PARAMETER["False_Easting",0.0],PARAMETER["False_Northing",0.0],PARAMETER["Central_Meridian",0.0],PARAMETER["Standard_Parallel_1",0.0],PARAMETER["Auxiliary_Sphere_Type",0.0],UNIT["Meter",1.0],AUTHORITY["EPSG",3857]]',
            ExtentType: 'Dynamic',
            Extent: 'OSGeo.MapGuide.ObjectModels.Common.FdoSpatialContextListSpatialContextExtent',
            XYTolerance: 0,
            ZTolerance: 0,
            IsActive: true
        },
        FeatureSchema: {
            Name: "Default",
            Description: "Default Schema",
            ClassDefinition: [
                {
                    Name: "DrawingResults",
                    Description: "Drawing geometry results",
                    PropertyDefinition: [
                        {
                            IsIdentity: true,
                            Name: "QBID",
                            PropertyType: 100, //MgFeaturePropertyType.DataProperty
                            DataType: 7, //MgPropertyType.Int32
                            Nullable: false,
                            IsAutoGenerated: true,
                            ReadOnly:true
                        }
                        ,
                        {
                            Name: "Geometry",
                            PropertyType: 102, //MgFeaturePropertyType.GeometricProperty
                            GeometryTypes: (1 | 2 | 4), //MgFeatureGeometricType.Point|Curve|Surface
                            SpatialContextAssociation: "EPSG:3857"
                        }
                    ]
                }
            ]
        }
    }
}

}`

However, the coordinate system of the SDF remain unknown.

I tried to use fusion layout red line tool to draw an rectangle, and downloaded the SDF file. However, the coordinate system is not recognized by Map 3D.

DrawingResults.zip

Same result generated by the new geo-processing example too. It's recognized by Map 3D as SDF with LL84 coordinate system. However, I wasn't able to perform the coordinate transformation too.

GeoProcessingResults.zip

image

jumpinjackie commented 7 years ago

Can you confirm that the WKT you are passing in is the same string that is returned by

/rest/coordsys/mentor/WGS84.PseudoMercator/wkt.json

?

RenoSun commented 7 years ago

Here's the WKT string through /rest/coordsys/mentor/WGS84.PseudoMercator/wkt.json

{"PrimitiveValue":{"Type":"String","Value":"PROJCS[\"WGS84.PseudoMercator\",GEOGCS[\"LL84\",DATUM[\"WGS84\",SPHEROID[\"WGS84\",6378137.000,298.25722293]],PRIMEM[\"Greenwich\",0],UNIT[\"Degree\",0.017453292519943295]],PROJECTION[\"Popular Visualisation Pseudo Mercator\"],PARAMETER[\"false_easting\",0.000],PARAMETER[\"false_northing\",0.000],PARAMETER[\"central_meridian\",0.00000000000000],UNIT[\"Meter\",1.00000000000000]]"}}

They're different strings. Then, I changed my CoordinateSystem parameter with the same string too.

The WKT geom printed from createInsertJson is in WGS84.PseudoMercator looks like following:

wktgeom: POLYGON((-13851879.6706238 6333778.8297116,-13851880.5891674 6333576.0804651,-13851880.5891826 6333576.0734859,-13851880.5870834 6333575.9930782,-13851880.5807917 6333575.9128966,-13851880.5703228 6333575.833149......-13851879.5036634 6333779.5202264,-13851879.5381928 6333779.4476352,-13851879.5688843 6333779.3733206,-13851879.5956583 6333779.2974904,-13851879.6184386 6333779.2203645,-13851879.6371609 6333779.142163,-13851879.6517793 6333779.0630815,-13851879.6622482 6333778.9833278,-13851879.6685399 6333778.903134,-13851879.6706238 6333778.8297116))

` function createInsertJson(geoms) {

var features = [];
for (var i = 0; i < geoms.length; i++) {
    features.push({
        Property: [
            { Name: "Geometry", Value: geoms[i] }
        ]
    });
    console.log('wktgeom: ' + geoms[i]);
}
var json = {
    FeatureSet: {
        Features: {
            Feature: features
        }
    }
};
return json;

}`

jumpinjackie commented 7 years ago

Firstly, where are you sourcing your WKT for the create feature source call? Because it isn't the same as the one returned by /rest/coordsys/mentor/WGS84.PseudoMercator/wkt.json

Secondly, you can leave out CoordinateSystemName, CoordinateSystemWkt, ExtentType and Extent from your spatial context section of the feature source parameters. This API will only ever be creating file-based (SDF/SHP/SQLite) feature sources and none of the above values apply for any SCs created. CoordinateSystem is what mapguide-rest will pick up as the WKT of the spatial context to create

RenoSun commented 7 years ago

Firstly, I get the selection feature geometry from mapguide-rest, and I get the WKT from the geojson.

Secondly, I sent the WKT to mapguide-rest geo-processing service , and get the buffered geojson.

Thirdly, I asked the user if he/she would like to save the buffer feature to the map layer.

` function BufferTheFeature(featureIndex, sessionID, mapName, layerName) { swal({ title: 'Please Enter The Buffer Distance', html: '' + '', showCancelButton: true, confirmButtonText: 'Submit', showLoaderOnConfirm: true, preConfirm: function () { return new Promise(function (resolve, reject) { if (!isNaN($('#bufferDist').val())) { $.getJSON("http://localhost/mapguide/rest/session/" + sessionID + "/" + mapName + ".Selection/features.geojson/" + layerName + "?transformto=WGS84.PseudoMercator&pagesize=1&page=" + featureIndex + "&mappedonly=1&displayproperties=1&includegeom=1", function (data) { $.each(data.features, function (key, val) { var geojson = val.geometry; var buffFeatures = (new ol.format.GeoJSON()).readFeatures(geojson); //original geometry WKT before buffer var orgGEOM = GeomToWKT(buffFeatures[0].getGeometry());

                        if ($('#bufferDist').val() >= 1 && $.isNumeric($('#bufferDist').val())) {
                            var args = {
                                geometry: orgGEOM,
                                coordsys: "WGS84.PseudoMercator",
                                distance: $('#bufferDist').val(),
                                units: $('#bufferUnit').val(),
                                format: "geojson"
                            };

                            $.ajax({
                                url: "http://localhost/mapguide/rest/processing/buffer",
                                type: "POST",
                                data: args
                            }).done(function (res) {
                                buffFeatures = (new ol.format.GeoJSON()).readFeatures(res.result);
                                var buffGeom = buffFeatures[0].getGeometry();
                                var buffGeomType = buffGeom.getType();
                                //console.log(GeomToWKT(buffGeom));

                                vectorDrawingSource.clear();
                                $('#drawinggeomtype').val(buffGeomType);
                                if (buffGeomType == 'Point') {
                                    $('#drawingPointSize').val(0.5);
                                    $('#drawingPointSizeUnit').val('Meters');
                                } else if (buffGeomType == 'LineString') {
                                    $('#drawingLineThickness').val(0.5);
                                    $('#drawingLineThicknessUnit').val('Meters');
                                }
                                $('#drawinggeomtype').change();
                                drawingOnMap();

                                vectorDrawingSource = new ol.source.Vector({
                                    features: buffFeatures
                                });

                                // create a vector layer for selection
                                vectorDrawing = new ol.layer.Vector({
                                    name: 'Drawing Layer',
                                    source: vectorDrawingSource,
                                    style: new ol.style.Style({
                                        fill: new ol.style.Fill({
                                            color: 'rgba(255, 255, 255, 0.0)'
                                        }),
                                        stroke: new ol.style.Stroke({
                                            color: '#ffcc00',
                                            width: 3
                                        }),
                                        image: new ol.style.Circle({
                                            radius: 3,
                                            fill: new ol.style.Fill({
                                                color: '#ffcc33'
                                            })
                                        })
                                    })
                                });
                                map.addLayer(vectorDrawing);
                                view.fit(vectorDrawingSource.getExtent(), animOption)
                                if (($("#selectionInfoTab").parent().hasClass("active")) && isMobile) {
                                    $("#selectionInfoTab").click();
                                }
                                resolve();
                            });
                        }
                        else if ($('#bufferDist').val() == 0) {
                            var buffFeatures = (new ol.format.GeoJSON()).readFeatures(geojson);
                            console.log(GeomToWKT(buffFeatures[0].getGeometry()));
                            var buffGeom = buffFeatures[0].getGeometry();
                            var buffGeomType = buffGeom.getType();

                            //vectorDrawingSource.clear();
                            $('#drawinggeomtype').val(buffGeomType);
                            if (buffGeomType == 'Point') {
                                $('#drawingPointSize').val(0.5);
                                $('#drawingPointSizeUnit').val('Meters');
                            } else if (buffGeomType == 'LineString') {
                                $('#drawingLineThickness').val(0.5);
                                $('#drawingLineThicknessUnit').val('Meters');
                            }
                            $('#drawinggeomtype').change();
                            drawingOnMap();

                            vectorDrawingSource = new ol.source.Vector({
                                features: buffFeatures
                            });

                            // create a vector layer for selection
                            vectorDrawing = new ol.layer.Vector({
                                name: 'Drawing Layer',
                                source: vectorDrawingSource,
                                style: new ol.style.Style({
                                    fill: new ol.style.Fill({
                                        color: 'rgba(255, 255, 255, 0.0)'
                                    }),
                                    stroke: new ol.style.Stroke({
                                        color: '#ffcc00',
                                        width: 3
                                    }),
                                    image: new ol.style.Circle({
                                        radius: 3,
                                        fill: new ol.style.Fill({
                                            color: '#ffcc33'
                                        })
                                    })
                                })
                            });
                            map.addLayer(vectorDrawing);
                            view.fit(vectorDrawingSource.getExtent(), animOption)
                            if (($("#selectionInfoTab").parent().hasClass("active")) && isMobile) {
                                $("#selectionInfoTab").click();
                            }
                            resolve();
                        }
                        else {
                            reject('Invalid Buffer Distance');
                        }
                    });

                });

            } else {
                reject('Invalid Buffer Distance');
            }
        })
    },
    allowOutsideClick: true
}).then(function (result) {
    swal({
        type: 'success',
        title: 'Buffer geometry has been generated!',
        html: 'Buffer Distance: ' + $('#bufferDist').val() + ' ' + $('#bufferUnit').val(),
        allowOutsideClick: false
    }).then(function () {
        swal({
            title: 'Last Step',
            text: "Would you like to convert the buffer drawing to a GIS layer?",
            type: 'question',
            showCancelButton: true,
            confirmButtonText: 'Yes',
            cancelButtonText: 'No',
            allowOutsideClick: false
        }).then(function () {
            if (!($("#drawingTab").parent().hasClass("active"))) {
                $("#drawingTab").click();
                $(".bufferHide").hide();
            }
        })
    })
})

} `

Fourthly, they click on the Convert Drawings To A Map Layer button to trigger the event (saveToLayer) using the current feature geometry from vectorDrawingSource features.

<input type="button" value="Convert Drawings To A Map Layer" id="drawingToGISLayer" class="btn btn-primary btn-block" />

` $('#drawingToGISLayer').on('click', function () { ... saveToLayer(); map.removeInteraction(drawingDraw); vectorDrawingSource.clear(); drawingOnMap(); drawingControlDisplay(); })

function saveToLayer() { var restUrl = "http://localhost/mapguide/rest"; counter++;

//Collect WKTs of Draw result layer
var geoms = [];
//resultsLayer.getSource().getFeatures();
var features = vectorDrawing.getSource().getFeatures();
var extent = ol.proj.transformExtent(vectorDrawing.getSource().getExtent(), 'EPSG:3857', 'EPSG:4326');
for (var i = 0; i < features.length; i++) {
    //console.log(features[i].getGeometry());
    drawingWKTFormat = new ol.format.WKT();
    var feat = features[i];
    if ($("#drawinggeomtype").val() == "Circle") {
        features[i].setGeometry(ol.geom.Polygon.fromCircle(features[i].getGeometry(), 32, 0));
    }
    console.log(drawingWKTFormat.writeFeature(feat));
    geoms.push(drawingWKTFormat.writeFeature(feat));
}
if (features.length > 0) {
    var drawingLayerName = $('#drawingLabName').val() + "_DL" + counter ;
    if ($('#drawingLabName').val() == '' || $('#drawingLabName').val() == null) {
        drawingLayerName = "DrawingResult_DL" + counter;
    }

    var url = restUrl + "/session/" + sessionId + "/" + mapName + ".Map/layersandgroups.json";

    var makeFeatureSource = function () {
        return $.ajax({
            url: restUrl + "/session/" + sessionId + "/" + drawingLayerName + ".FeatureSource/json",
            type: "POST",
            data: JSON.stringify(createFeatureSourceJson())
        })
    };
    var createLayerDef = function (data, textStatus, jqXHR) {
        return $.ajax({
            url: restUrl + "/session/" + sessionId + "/" + drawingLayerName + ".LayerDefinition/content.json",
            type: "POST",
            data: JSON.stringify(createLayerDefJson("Session:" + sessionId + "//" + drawingLayerName + ".FeatureSource", "Default:DrawingResults", "Geometry", $('#drawingColor').val().replace('#', '')))
        });
    };
    var insertDrawingResult = function (data, textStatus, jqXHR) {
        return $.ajax({
            url: restUrl + "/session/" + sessionId + "/" + drawingLayerName + ".FeatureSource/features.json/Default/DrawingResults",
            type: "POST",
            processData: false,
            data: JSON.stringify(createInsertJson(geoms))
        })
    };
    var addLayerToMap = function (data, textStatus, jqXHR) {
        return $.ajax({
            url: restUrl + "/session/" + sessionId + "/" + mapName + ".Map/layersandgroups.json",
            type: "POST",
            data: JSON.stringify(addLayerJson("Session:" + sessionId + "//" + drawingLayerName + ".LayerDefinition", drawingLayerName)),
            beforeSend: function (xhr) {
                xhr.setRequestHeader("X-HTTP-Method-Override", "PUT");
            }
        });
    };

    makeFeatureSource()
        .then(createLayerDef)
        .then(insertDrawingResult)
        .then(addLayerToMap)
        .then(function () {
            swal(
                'Success',
                'Your drawing was converted to the GIS layer!',
                'success'
            ).then(function () {
                //    openInNewTab(restUrl+'/session/' + sessionId+'/' + drawingLayerName+'.LayerDefinition/kmlfeatures?bbox=' + extent[0] + ',' + extent[1]+','+ extent[2]+','+ extent[3]+'&dpi=96&width=1&height=1&draworder=1');
                kmlDownloadHrefList.push(restUrl + '/session/' + sessionId + '/' + drawingLayerName + '.LayerDefinition/kmlfeatures.kml?bbox=' + extent[0] + ',' + extent[1] + ',' + extent[2] + ',' + extent[3] + '&dpi=96&width=1&height=1&draworder=1');
                kmlDownloadTextList.push(drawingLayerName+' (KML)');
            })
            MgLayersRedraw();
            //MgLayersRedraw();
            //clearResults();
            var reqFeatures = (1 | 2 | 4);
            //Re-query layer structure from server
            $.getJSON(restUrl + "/session/" + sessionId + "/" + mapName + ".Map/description.json?requestedfeatures=" + reqFeatures).then(function (res) {
            });
        });
}
else {
    swal(
        'Error',
        'You did not draw any features on the map',
        'error'
    )
}

}

`

RenoSun commented 6 years ago

Solved by change using SQLite as FeatureSourceParams: Provider: "OSGeo.SQLite", FileName: "DrawingResults.SQLite"

Won't work if I am using SDF as provider.