Google Maps - FusionTablesLayer to Polygon
Asked Answered
C

1

9

I'm using Google Maps API and jquery-ui-maps (this questions has nothing to do with the plugin which is working great).

I've created a FusionTablesLayer with all countries except Mozambique. The user could place a marker and reposition it. I'm trying to find a way to block the drag (or alert the user, it doesn't matter now) if he tries to place the marker outside Mozambique (over the FusionTablesLayer).

After some research I discover this method: containsLocation(point:LatLng, polygon:Polygon), which computes whether the given point lies inside the specified polygon.

It should receive a Polygon and I've got a FusionTablesLayer. Any clue how to solve this?

Here's my code:FIDDLE

Try to place a marker and drag it...

//Initialize the map
var mapa = $('#map_canvas').gmap({'center': '-18.646245,35.815918'});
$('#map_canvas').gmap('option', 'zoom', 7);

//create the layer (all countries except Mozambique)
var world_geometry;
$('#map_canvas').gmap().bind('init', function(event, map) {
    world_geometry = new google.maps.FusionTablesLayer({
        query: {
            select: 'geometry',
            from: '1N2LBk4JHwWpOY4d9fobIn27lfnZ5MDy-NoqqRpk',
            where: "ISO_2DIGIT NOT EQUAL TO 'MZ'"
        },
        styles: [{
                polygonOptions: {
                    fillColor: "#333333",
                    fillOpacity: 0.3
                }
            }],
        map: map,
        suppressInfoWindows: true
    });

});

$('#map_canvas').gmap().bind('init', function(event, map) {
    $(map).click(function(event) {
        $('#map_canvas').gmap('clear', 'markers');
        $('#map_canvas').gmap('addMarker', {
            'position': event.latLng,
            'draggable': true,
            'bounds': false
        }, function(map, marker) {
        }).dragend(function(event) {
            //I need to check if the marker is over the FusionTablesLayer and block the drag.
            //var test = google.maps.geometry.poly.containsLocation(event.latLng, world_geometry);
        }).click(function() {
        })
    });
});
Corollaceous answered 23/2, 2014 at 3:46 Comment(0)
T
5

Since there is no containsLocation in FusionTablesLayer, and since no mouseevents but click is supported (that would have made it a lot easier) - there is no other way round than to check if there is being dragged outside the area itself, Mozambique - not into the FusionTablesLayer. The solution is to create an invisible polygon for Mozambique, and use that polygon to check for containsLocation when dragging is finished.

The polygon can be based on the KML from the row you are excluding, MZ. That can be done using google.visualization.Query.

1) include the Google API loader in your project :

<script type="text/javascript" src="https://www.google.com/jsapi"></script>

2) initialize Visualization :

google.load('visualization', '1.0');

3) define a variable for the polygon holding the Mozambique borders :

var mozambique;

The following is a function that loads the geometry data for Mozambique, and then creates an invisible polygon on the map; google.visualization.Query is used instead of the automated FusionTablesLayer so we can extract the <coordinates> from the KML and use them as base for the polygon.

In basic, this is how to convert KML-data from a FusionTable to a polygon :

function initMozambique(map) {
    //init the query string, select mozambique borders
    var sql = encodeURIComponent("SELECT 'geometry' FROM 1N2LBk4JHwWpOY4d9fobIn27lfnZ5MDy-NoqqRpk WHERE ISO_2DIGIT ='MZ'");
    var query = new google.visualization.Query('http://www.google.com/fusiontables/gvizdata?tq=' + sql);
    query.send(function (response) {
        var data = response.getDataTable().getValue(0, 0);
        //create a XML parser
        if (window.DOMParser) {
            var parser = new DOMParser();
            var kml = parser.parseFromString(data, "text/xml");
        } else { // Internet Explorer 
            var kml = new ActiveXObject("Microsoft.XMLDOM");
            kml.loadXML(data);
        }
        //get the coordinates of Mozambique
        var latLngs = kml.getElementsByTagName("coordinates")[0].childNodes[0].nodeValue.split(' ');
        //create an array of LatLngs
        var mzLatLngs = [];
        for (var i = 0; i < latLngs.length; i++) {
            var latLng = latLngs[i].split(',');
            //<coordinates> for this FusionTable comes in lng,lat format
            mzLatLngs.push(new google.maps.LatLng(latLng[1], latLng[0]));
        }
        //initialize the mozambique polygon
        mozambique = new google.maps.Polygon({
            paths: mzLatLngs,
            fillColor: 'transparent',
            strokeColor : 'transparent',
            map: map
        });
        //make the mozambique polygon "transparent" for clicks (pass clicks to map)
        google.maps.event.addListener(mozambique, 'click', function(event) {
            google.maps.event.trigger(map, 'click', event);
        });
    });
}

Call the above initMozambique function in your second gmap().bind('init'... :

$('#map_canvas').gmap().bind('init', function(event, map) {
   initMozambique(map);
   ...

Now you can check the mozambique-polygon for containsLocation after dragging

...
}).dragend(function(event) {
  if (!google.maps.geometry.poly.containsLocation(event.latLng, mozambique)) {
     alert('You are not allowed to drag the marker outside Mozambique');
  }
  //I need to check if the marker is over the FusionTablesLayer and block the drag.
  //var test = google.maps.geometry.poly.containsLocation(event.latLng, world_geometry);
}).click(function() {
})
...

See forked fiddle, working demo with the code above -> http://jsfiddle.net/yb5t6cw6/

Tested in Chrome, FF and IE, ubuntu and windows.

Tumefacient answered 28/2, 2014 at 13:32 Comment(5)
I haven't got time to test it by myself but it makes all sense! Thx for your detailed answer.Corollaceous
@Tumefacient But in case one country have too many polygon. How can we handle it?Lechner
@QuỳnhNguyễn, thanks for pointing me to this old answer. Have updated the fiddle, the old one did no longer work due to outdated CDN's. I am not sure, which country do you have in mind?Tumefacient
@Tumefacient jsfiddle.net/srxnu8pc Here is my fusion table layer. And I'm trying check drag marker inside or outside these zone. And I'm sorry because your solutions can't apply for this case. Because we can't query NOT EQUAL...Lechner
@Tumefacient I already try google.visualization.Query and ST_INTERSECTS of Circle with geometry data. But have a little delay because query too heavy... Can you understand sir?Lechner

© 2022 - 2024 — McMap. All rights reserved.