0

I am using a lasso tool to allow users to draw polygons on a google map. Once the lasso tool is done, a polygon is saved as json, and conformed to fit into a SQL Server geography field.

My problem is how the polygon is captured from the map in javascript:

function Polygon() {

    //metadata
    this.polygon = null;
    this.polygon_ = null;
    this.tract = null;
    this.zip = null;
    this._zip = null;
    this.user = null;
    this.name = null;

    //polygon definitions
    this.linecolor = "#000000";
    this.fillcolor = "#000000";
    this.opacity = 0.7;
    this.type = "geoid";
    this.strokeweight = 2;

    //circle dimensions
    this.center = null;
    this.radius = null;

    //rectangle dimensions
    this.north = null;
    this.south = null;
    this.east = null;
    this.west = null;

    //polygon dimensions
    this.vertices = [];
    this.jsonpoints = [];
    this.bounds = null;

    this.getverticies = function () {
        //TODO: get polygon
        if (this.type === 'polygon') {
            this.bounds = new google.maps.LatLngBounds();
            points = JSON.parse(this.jsonpoints);
            for (var i=0; i<points.length; i++) {
                var point = new google.maps.LatLng(points[i].lat, points[i].lng);
                // this.ispointinpoly(point);
                this.vertices[i] = point;
                this.bounds.extend(point);
            }
        }

    };

    this.gettheBounds = function () {
        this.bounds = this.polygon.getDefaultViewport();
    };

    this.setkml = function() {

    };

    this.plot = function (map) {
        if(this.type == 'polygon') {
            this.getverticies();
            this.polygon = new google.maps.Polygon({
                paths: this.vertices,
                strokeColor: this.linecolor,
                strokeWeight: this.strokeweight,
                fillColor: this.fillcolor,
                fillOpacity: this.opacity,
                map: map
            })
        }
        else if (this.type == 'circle'){
            lat = this.center.substring(this.center.lastIndexOf("(")+1,this.center.lastIndexOf(",")).trim();
            lng = this.center.substring(this.center.lastIndexOf(",")+1,this.center.lastIndexOf(")")).trim();
            this.polygon = new google.maps.Circle({
                strokeColor: this.linecolor,
                strokeOpacity: this.opacity,
                strokeWeight: this.strokeweight,
                fillColor: this.fillcolor,
                fillOpacity: this.opacity,
                map: map,
                center: new google.maps.LatLng(lat, lng),
                radius: this.radius
            })
        }
        else if (this.type == 'rectangle'){
            this.polygon = new google.maps.Rectangle({
                strokeColor: this.linecolor,
                strokeOpacity: this.opacity,
                strokeWeight: this.strokeweight,
                fillColor: this.fillcolor,
                fillOpacity: this.opacity,
                map: map,
                bounds: {
                    north: this.north,
                    south: this.south,
                    east: this.east,
                    west: this.west
                }
            })
        }
        else if (this.type == 'geoid'){
            var url = window.location.protocol + "//" + window.location.host + "/v7/app_territorybuilder/data/GET_GEOID.cfm?TYPE=GEOID&VALUE=" + this.zip + "&LC=641400FF&LW=3&FC=14F11C2E&F=1&FO=1&zip="+this.zip;
            // var url = window.location.protocol + "//" + window.location.host + "/v5/GIStest/data/GET_GEOID.cfm?TYPE=GEOID&VALUE=" + this.tract + "&LC=641400FF&LW=3&FC=14F11C2E&F=1&FO=1&zip="+this.zip;
            // var url = window.location.protocol + "//" + window.location.host + "/v5/GIStest/data/GET_ZIP.cfm?TYPE=GEOID&VALUE=" + this.tract + "&LC=641400FF&LW=3&FC=14F11C2E&F=1&FO=1";
            this.polygon_ = new google.maps.KmlLayer(url,
            {
                suppressInfoWindows: true,
                // suppressInfoWindows: false,
                preserveViewport: false,
                map: map.map
            });
            
        }
    };

    this.ispointinpoly = function(point,p){
        return google.maps.geometry.poly.containsLocation(point, p)
        // return google.maps.geometry.poly.containsLocation(point, this.polygon)
    };

    this.savedrawingaspoly = function(event){
        this.center = null;
        this.radius = null;
        this.north = null;
        this.south = null;
        this.vertices = [];
        this.jsonpoints = [];

        this.type = event.type;
        
        if (this.type === 'circle') {
            this.type = event.type;
            this.center = event.overlay.center;
            this.radius = event.overlay.radius;
        } else if (this.type === 'rectangle'){
            this.north = event.overlay.getBounds().getNorthEast().lat();
            this.south = event.overlay.getBounds().getSouthWest().lat();
            this.east = event.overlay.getBounds().getNorthEast().lng();
            this.west = event.overlay.getBounds().getSouthWest().lng();

    
        } else if (this.type === 'polygon'){
            var points = event.overlay.getPath();
            console.log(points);
            console.log(event.overlay.getPaths());
            var stringer = '[';
            for (var i = 0; i < points.getLength() ; i++) {
                var xy = points.getAt(i);
                stringer = stringer + ('{"lng":'+xy.lng()+',"lat":'+xy.lat()+'},');
            }
            xy = points.getAt(0);
            this.jsonpoints = stringer + '{"lng":'+xy.lng()+',"lat":'+xy.lat()+'}]';
        }
        
    };

    this.saveaoi = function() {
        var datajson = "zip=" + this.zip;//.toString();
        // var datajson = "tract=" + this.tract.toString();
        // datajson = datajson + "&user=" + this.user.toString(); //Commented by umer on 2019/10/22
        datajson = datajson + "&name=" + this.name.toString();
        datajson = datajson + "&type=" + this.type.toString();
        datajson = datajson + (this.center ? "&center=" + this.center.toString(): '');
        datajson = datajson + (this.radius ? "&radius=" + this.radius.toString(): '');
        datajson = datajson + (this.north ? "&north=" + this.north.toString(): '');
        datajson = datajson + (this.south ? "&south=" + this.south.toString(): '');
        datajson = datajson + (this.east ? "&east=" + this.east.toString(): '');
        datajson = datajson + (this.west ? "&west=" + this.west.toString(): '');
        datajson = datajson + (this.jsonpoints ? "&vertices=" + this.jsonpoints.toString(): '');

        var request = new XMLHttpRequest();
        request.onreadystatechange = function() {
            if (this.readyState == 4 && this.status == 200) {
                console.log(JSON.parse(this.responseText));
               window.top.location.href = JSON.parse(this.responseText).RETURNURL;
            }
        };
        request.open('GET', './data/SAVE_AOI.cfm?' + datajson, true);
        request.send();

    };

    this.setaoidata = function(DATA) {
        if (DATA[0][3] == 'circle'){
            this.type = DATA[0][3];
            this.center = DATA[0][4];
            this.radius = DATA[0][5];
        }
        else if (DATA[0][3] == 'rectangle'){
            this.type = DATA[0][3];
            this.north = DATA[0][6];
            this.south = DATA[0][7];
            this.east = DATA[0][8];
            this.west = DATA[0][9];
        }
        else if (DATA[0][3] == 'polygon'){
            this.type = DATA[0][3];
            this.jsonpoints = DATA[0][10]
        }
    };

    this.getaoi = function() {
        // var datajson = "tract=" + tract.toString();
        var datajson = "zip=" + this.zip;//.toString();
        // datajson = datajson + "&user=" + user.toString();
        datajson = datajson + "&id=" + this.tract.toString();
        datajson = datajson + "&name=" + this.name.toString();

        var _self = this;

        var xhttp = new XMLHttpRequest();
        xhttp.onreadystatechange = function() {
            if (this.readyState === 4 && this.status === 200) {
                _self.setaoidata(JSON.parse(this.responseText).DATA);
            }
        };
        xhttp.open('GET', './data/GET_AOI_DATA.cfm?' + datajson, false);
        xhttp.send();


    }

    this.setoptions = function() {
         this.polygon.setOptions({
             strokeColor: this.linecolor,
             strokeWeight: this.strokeweight,
             fillColor: this.fillcolor,
             fillOpacity: this.opacity
         });
    };

}

when the polygon is captured, I attempt to save it using an updated command:

UPDATE [AOI]
        SET [geography] =
        CASE [type]
            WHEN 'circle' THEN GEOGRAPHY::STGeomFromText ('point('+dbo.GetLng(center)+' '+ dbo.GetLat(center)+')',4326)
            WHEN 'rectangle' THEN geography::STGeomFromText('POLYGON(('+try_cast(east as varchar(100))+' '+try_cast(north as varchar(100))+', '+try_cast(west as varchar(100))+' '+try_cast(north as varchar(100))+', '+try_cast(west as varchar(100))+' '+try_cast(south as varchar(100))+', '+try_cast(east as varchar(100))+' '+try_cast(south as varchar(100))+', '+try_cast(east as varchar(100))+' '+try_cast(north as varchar(100))+'))', 4326)
            WHEN 'polygon' THEN geography::STGeomFromText('POLYGON(' + replace(replace(replace(replace(replace(vertices,'{"lng":',''),',"lat":',' '),'[','('),']',')'),'}','') + ')', 4326)
        END
        WHERE  
        [zip] = #URL.zip#
        AND [user] = #cookie.UserID#
        AND [name] = '#URL.name#';

when a user creates a polygon counter-clockwise, the save works, but if the polygon is drawn by the user clockwise, the geography fails to save.

My question is simple. I can use ReOrientate() in SQL to export out a proper geography polygon in SQL. How can I re-orientate the nodes in javascript so I can save it properly in SQL?

Rationale...

We call the geography field in order to perform GIS and reposting back onto the google maps. If the order is wrong, the reorientate() does not work, I get points outside the polygon. I need to standardize the order of the nodes in the polygon so this does not happen.

Thank you.

arcee123
  • 101
  • 9
  • 41
  • 118
  • 2
    Why don't you just check the order of the coordinates in the javascript, if it is backwards, reverse it? – geocodezip Jan 27 '23 at 06:18
  • so, my question is how do I know I'm out of order, and how do I set the order....that's my question. – arcee123 Jan 27 '23 at 18:21
  • possible duplicate of [how to order vertices in a non-convex polygon (how to find one of many solutions)](https://stackoverflow.com/questions/19713092/how-to-order-vertices-in-a-non-convex-polygon-how-to-find-one-of-many-solutions) – geocodezip Jan 27 '23 at 20:38
  • possible duplicate of [Sort points in clockwise order?](https://stackoverflow.com/questions/6989100/sort-points-in-clockwise-order) – geocodezip Jan 27 '23 at 20:39

0 Answers0