12

Roughly a week ago, I ran into a problem: on a custom google-powered map, my Polygons would not show up, while Markers for the same coordinates are totally ok. Despite my efforts with the Google Maps API, it seems I cannot find why.

Here is a link to a screenshot of the map. Purple arrows and numbers are my addition, they show:

  1. The google.maps.Marker I could place at the edges of my "region".
  2. The artifact generated by the google.maps.Polygon code. It is red as expected, but completely out of place and weirdly flat.

Here is the part of the code where Markers and Polygons are generated:

var regionData = tecMap.regions[r];
var regionMapMarkers = new google.maps.MVCArray();

for (c in regionData.coords) {
    var point = projection.worldToMap(regionData.coords[c]);
    debugRegionPoints.push(point);
    var thisLatLng = projection.fromPointToLatLng(point);
    debugRegionLatLngs.push(thisLatLng);
    regionMapMarkers.push(thisLatLng);
}

regionMapMarkers.forEach(function(latLng, m){
    var marker = new google.maps.Marker({       
        position: latLng,
        map: map, 
        title: '',
        optimized: false
    });
    regionCorners.push(marker);
});

var paths = new google.maps.MVCArray();
paths.push(regionMapMarkers);

var region = new google.maps.Polygon({
    fillColor: "#FF0000",
    fillOpacity: 0.35,
    map: map,
    paths: paths,
    strokeColor: "#FF0000",
    strokeOpacity: 0.8,
    strokeWeight: 2     
});
regionPolys.push(region);

If you're wondering about the array of arrays, it's all on par with the Google Maps Javascript API.

If you want to have a look at the map and related scripts, you can find it here. The code snippet is in Scripts/tectonicus.js, starting at line 659.

[Edit] Some debugging information:

It seems to be a rendering problem, not a "calculating" one. From firebug console, in the map I linked, both

regionPolys[0].getPath().getArray();

and

for (i in regionCorners) {console.log(regionCorners[i].getPosition())};

will return

P { Na=0.20123958504464223, Oa=-22.5249097921875}
P { Na=-0.21702715474330336, Oa=-32.7277467}
P { Na=0.19466306397879407, Oa=-37.51230686484375}
P { Na=0.12889785332031245, Oa=-49.04594858671875}

If I'm right, it means they have the same coordinates, which is on par with the code.

[Edit2] New advances !

It seems that vectors have rendering problems when dealing with a custom projection, such as the one used to display this isometric Minecraft map. (Generated with Tectonicus)

After the last comments, I'm adding to the live code linked above two new debug Arrays, debugRegionLatLngs and debugRegionPoints. Above code is updated so you can see what they contain.

[Edit3] Projection and coordinates

Crossing BicycleDude's research with mine, it's now almost certain that it's the custom projection that wrecks polygons. In fact, there is a possibly related bug in Google Maps' API.

This projection is used because Minecraft maps can be virtually infinite, and yet have to use a gmap, which wraps around after 360° longitude. Also related is the fact that ingame coordinates are rendered in an isometric way, while gmaps expects something more like the Mercator projection.

I tried tweaking the projection a bit, but had no interesting results so far.

Silver Quettier
  • 2,045
  • 2
  • 26
  • 53
  • 1
    I believe you're using `path` in the polygon properties, when in fact it should be `paths` Otherwise, it would help to see live code somewhere. Cheers, Andres – andresf Jan 09 '12 at 20:27
  • I foudn some space to upload a copy of the map and related code. Link is in the question. If there is any test you would like me to run, please ask. :) – Silver Quettier Jan 11 '12 at 18:26
  • Can you post a slightly smaller sample that reproduces this, or at least point us to the Google Maps code in your sample? I'm getting lost in all the JavaScript files... – bamnet Jan 13 '12 at 05:59
  • @bamnet Sorry, I did not include this in my last edit. The part of code you're looking for is in `Scripts/tectonicus.js`, starting at line 659. Editing the main post with this. – Silver Quettier Jan 13 '12 at 07:39
  • I went through the objects with FireBug's console. Added my results to the OP. It makes no sense to me, everything should work. – Silver Quettier Jan 16 '12 at 18:41
  • 3
    After taking a look at this some more I think that your custom projection (whatever it is that you're using for the "minecraft" projection) is what is giving you the weird behavior. The coordinates for your polygon seem really odd. The delta between longitudes is various degrees, but the delta in latitudes is decimals. I suggest using the following code to see how the coordinates don't really follow the standard north/south east/west logic on your map. --- google.maps.event.addListener(map, 'click', function(e) { alert(e.latLng.lat()+', '+e.latLng.lng()); }); – andresf Jan 20 '12 at 04:49
  • I reviewed the coordinates, and the are a flat sliver polygon near the equator. I am currently investigating whether this is connected to the isometric projection caused by tecMap. Ideally logging needs to be added for point and thisLatLng. – Stephen Quan Jan 20 '12 at 21:26
  • @BicycleDude - I added some logging for point and thisLatLng, as you requested. I'm more and more convinced that this is due to the projection indeed. – Silver Quettier Jan 21 '12 at 16:48

2 Answers2

4

Hmm, I looked at this further and I do see that sliver polygon. If you note your latitudes, they're extremely close to 0 degrees which means virtually a flat line near the equator. I validated this myself by pasting your coordinates into a brand new Google Maps sample and they do not appear to be spatially located with your markers, so, you need to review where the coordinate information is being manipulated, sorry, I know I didn't find your problem.

I modified Google Map's Bermuda triangle sample to use your coding style. i.e. I adopted your variables and followed the spirit of your code. This example display 3 markers and the draws a polygon for the Bermuda triangle.

<!DOCTYPE html>
<html>
  <head>
    <title>Bermuda Hack Triangle</title>
    <meta name="viewport"
        content="width=device-width, initial-scale=1.0, user-scalable=no">
    <meta charset="UTF-8">
    <style type="text/css">
      #map_canvas {
        width: 500px;
        height: 500px;
      }
    </style>
    <script type="text/javascript" scr="https://github.com/douglascrockford/JSON-js/blob/master/json2.js"></script>
    <script type="text/javascript"
        src="http://maps.googleapis.com/maps/api/js?sensor=false"></script>
    <script type="text/javascript">
      var map;
      function initialize() {
        var myoptions = {
            zoom: 4,
            center: new google.maps.LatLng(25, -70),
            mapTypeId: google.maps.MapTypeId.ROADMAP
        };
        map = new google.maps.Map(
          document.getElementById('map_canvas'),
          myoptions
        );

        // Create pseudo coordinates
        var regionMapMarkers = new google.maps.MVCArray();
        var p1 = new google.maps.LatLng(25, -80);
        var p2 = new google.maps.LatLng(18, -66);
        var p3 = new google.maps.LatLng(32, -64);
        //p2.Qa += 360;
        //p3.Qa -= 360;
        regionMapMarkers.push(p1);
        regionMapMarkers.push(p2);
        regionMapMarkers.push(p3);
        console.log(JSON.stringify(regionMapMarkers));

        // Draw Markers
        regionMapMarkers.forEach(function(latLng, m){
            var marker = new google.maps.Marker(
            {        
            position: latLng,
            map: map, 
            title: '',
            optimized: false
            });
        });

        // Draw Polygon
        var region = new google.maps.Polygon({
          map: map,
          paths: regionMapMarkers,
          strokeColor: "#FF0000",
          strokeOpacity: 0.8,
          strokeWeight: 2,
          fillColor: "#FF0000",
          fillOpacity: 0.35
        });
      }

      google.maps.event.addDomListener(window, 'load', initialize);
    </script>
  </head>
  <body>
    <div id="map_canvas"></div>
  </body>
</html>

The sample works. If you were to run it you'll get the Bermuda triangle surrounded by markers. The question then lies, what can, in practice, impact your algorithm? So far, we've speculated that the Minecraft projection does something. I still believe that to be the case.

In order to validate that theory, I tried to wreck the Bermuda triangle sample. I tried adding and subtracting 360 degrees longitude to two points by uncommenting the following lines:

        p2.Qa += 360;
        p3.Qa -= 360;

What this does is it will still allow it to place the markers in the same location but the polygon fill goes absolutely spacko. I believe this is what is happening in your scenario.

What I then recommend for you to do is review coordinate system in your application. If you can choose new coordinates you can avoid such edge conditions from happening.

Stephen Quan
  • 21,481
  • 4
  • 88
  • 75
  • I think Google's functions are closing the polygon automatically if the last coordinate is not specified. Thanks for sharing your ideas and code. I'll continue doing some research. +1 because you spent some time on this. :) – Silver Quettier Jan 21 '12 at 23:47
  • Thanks @SilverFXQuettier. I've added additional research for you to look at. – Stephen Quan Jan 22 '12 at 00:57
  • What I do not understand is why these "thisLatLng" coordinates can be used to place a marker at the intended location, despite the weird "x" attribute. :/ – Silver Quettier Jan 22 '12 at 01:35
  • Thanks @SilverFxQuettier. I completely re-reviewed my analysis and updated my answer dramatically. In this version, I now agree with your algorithm entirely. I shifted focus to the Minecraft projection and potential coordinate system problems. – Stephen Quan Jan 22 '12 at 10:01
  • At least, we're advancing in the right direction. I am not the one who wrote the original projection (all this is an extension to [Tectonicus](http://triangularpixels.net/games/tectonicus/) ) and forwarded this information to the author. I tried fiddling a bit with the projection but got nothing interesting so far - see OP for details. – Silver Quettier Jan 24 '12 at 08:12
  • Yeah I manufactured some insane coordinates, but the red line still didn't budge. Then I set some insane strokeWeight, I think I used 20, then the line did changed, but it still look weird. I couldn't explain, it almost feels that there is dramatic clipping in the latitude's occurring. – Stephen Quan Jan 24 '12 at 10:18
0

I noticed you're passing paths as an MVCArray which contains another MVCArray. Have you tried just passing a simple single-dimension array like in Google's example in the docs?

And do you need to call setMap() or is passing in the map property enough to make it render?


Below is Google's Polygon() code example... (from here)

function initialize() {
  var myLatLng = new google.maps.LatLng(24.886436490787712, -70.2685546875);
  var myOptions = {
    zoom: 5,
    center: myLatLng,
    mapTypeId: google.maps.MapTypeId.TERRAIN
  };

  var bermudaTriangle;

  var map = new google.maps.Map(document.getElementById("map_canvas"),
      myOptions);

  var triangleCoords = [
    new google.maps.LatLng(25.774252, -80.190262),
    new google.maps.LatLng(18.466465, -66.118292),
    new google.maps.LatLng(32.321384, -64.75737),
    new google.maps.LatLng(25.774252, -80.190262)
  ];

  // Construct the polygon
  // Note that we don't specify an array or arrays, but instead just
  // a simple array of LatLngs in the paths property
  bermudaTriangle = new google.maps.Polygon({
    paths: triangleCoords,
    strokeColor: "#FF0000",
    strokeOpacity: 0.8,
    strokeWeight: 2,
    fillColor: "#FF0000",
    fillOpacity: 0.35
  });

  bermudaTriangle.setMap(map);
}
Simon East
  • 55,742
  • 17
  • 139
  • 133
  • 1
    Hello Simon - Sadly, yes, the problem occurs no matter if I use the `path` (single array) or `paths` attribute (array of arrays), and whether the map is set in the constructor or through the `setMap()` function. Thanks for having a look thus :) – Silver Quettier Jan 21 '12 at 10:22