Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Displaying crosshairs in the center of a JavaScript Google Map

I'd like to display a crosshair/reticule that's fixed in the center of a Google Map, just as Wikimapia.org do. Unfortunately they are using v2 of the API and I'm using v3.

The crosshair should remain fixed in the center as the user pans the map around.

There's no CENTER option for the ControlPosition enum, so I imagine any solution will be a bit hacky.

I've tried to overlay it as a div outside of the map, but I haven't managed to get it to display on top of the map -- it seems to get trumped in a z-order showdown.

like image 326
Drew Noakes Avatar asked Nov 09 '10 03:11

Drew Noakes


3 Answers

I stumbled upon this jsfiddle which handles this gracefully, with plain css! http://jsfiddle.net/egak/X5r8r/2351/

<div id="wrap1">
    <div id="map-canvas"></div>
    <div id="cross"></div>
</div>
#wrap1{
    width: 300px;
    height: 300px;
    position: relative;
}
#map-canvas{
    width: 100%;
    height: 100%;
}
#cross{
    position: absolute;
    width: 2px;
    height: 20px;
    background: #000;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%);
    pointer-events: none;
}
#cross::before{
    content: "";
    position: absolute;
    width: 20px;
    height: 2px;
    background: #000;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%);
}
new google.maps.Map(document.getElementById('map-canvas'),{
    zoom: 8,
    center: new google.maps.LatLng(-34.397, 150.644)
});

Credits to the author, http://jsfiddle.net/user/egak/

like image 132
Vincent Sels Avatar answered Oct 31 '22 17:10

Vincent Sels


I am using the solution I found at DaftLogic.com. It seems to be basically the same solution as BentFX but much more terse.

var marker = new google.maps.Marker({
    map: map,
    icon: '/images/reticle.png'
});
marker.bindTo('position', map, 'center'); 

Unfortunately it also suffers from the problem Drew noted where the crosshairs are not permanently fixed to the center of the map. If you drag the map quickly or zoom in and out, you will see the crosshairs move a little until it has time to be recentered. If anyone comes up with a better solution, please let us know.

like image 25
Garland Pope Avatar answered Oct 31 '22 16:10

Garland Pope


The given solution didn't work for me, because the overlying div creates a dead spot in the map. A better solution for my project, using the Google Maps JavaScript API V3, was to create the reticle on the map as a marker with a 1 pixel rectangle shape. Then use the maps bounds_changed event to recenter the marker.

Reticle image is 63 x 63 png. (images/reticle.png)

Define the marker image and shape...

  var reticleImage = new google.maps.MarkerImage(
    'images/reticle.png',            // marker image
    new google.maps.Size(63, 63),    // marker size
    new google.maps.Point(0,0),      // marker origin
    new google.maps.Point(32, 32));  // marker anchor point
  var reticleShape = {
    coords: [32,32,32,32],           // 1px
    type: 'rect'                     // rectangle
  };

After creation of our map (main_map) we add the marker...

  reticleMarker = new google.maps.Marker({
    position: latlng,
    map: main_map,
    icon: reticleImage, 
    shape: reticleShape,
    optimized: false,
    zIndex: 5
  });

Here the var latlng is the same LatLng object used to create main_map. The zIndex should be greater than any other marker zIndex's, to keep the reticle on top.

Then we add an event handler to be called when the map bounds_changed is fired.

  google.maps.event.addListener(main_map, 'bounds_changed', centerReticle);

and finally we have the centerReticle() function.

  function centerReticle(){
    reticleMarker.setPosition(main_map.getCenter());
  }

Since we're not doing anything else with the 'bounds_changed' event we can tidy up the code by passing an anonymous function to the addListener call... This keeps us from having to define the centerReticle() function.

  google.maps.event.addListener(main_map, 'bounds_changed',
      function(){reticleMarker.setPosition(main_map.getCenter());});

It actually works pretty slick. I hope this helps others.

Thanks.

Skip

like image 32
BentFX Avatar answered Oct 31 '22 15:10

BentFX