Skip to content
This repository was archived by the owner on Sep 4, 2025. It is now read-only.
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
110 changes: 64 additions & 46 deletions polysnapper.js
Original file line number Diff line number Diff line change
@@ -1,18 +1,18 @@
/*
_
| |
_ __ ___ | |_ _ ___ _ __ __ _ _ __ _ __ ___ _ __
_
| |
_ __ ___ | |_ _ ___ _ __ __ _ _ __ _ __ ___ _ __
| '_ \ / _ \| | | | / __| '_ \ / _` | '_ \| '_ \ / _ \ '__|
| |_) | (_) | | |_| \__ \ | | | (_| | |_) | |_) | __/ |
| .__/ \___/|_|\__, |___/_| |_|\__,_| .__/| .__/ \___|_|
| | __/ | | | | |
|_| |___/ |_| |_|
| |_) | (_) | | |_| \__ \ | | | (_| | |_) | |_) | __/ |
| .__/ \___/|_|\__, |___/_| |_|\__,_| .__/| .__/ \___|_|
| | __/ | | | | |
|_| |___/ |_| |_|

@jordanarseno - MIT LICENSE

*/
*/

function PolySnapper(opts){
function PolySnapper(opts){

function extend(obj) {

Expand All @@ -38,40 +38,40 @@ function PolySnapper(opts){
function defined(obj, key){
return typeof obj[key] !== 'undefined'
}

var that = this;

this.keyDownListener = null;
this.keyUpListener = null;

this.drawing = false;
this.currentpoly = null;
this.polys = ( defined(opts, 'polygons') )? opts.polygons : [];

var _map = ( defined(opts, 'map') )? opts.map : null;
var _marker = ( defined(opts, 'marker') )? opts.marker : new google.maps.Marker();
var _marker = ( defined(opts, 'marker') )? opts.marker : new google.maps.Marker();
var _thresh = ( defined(opts, 'threshold') )? opts.threshold : 20;
var _key = ( defined(opts, 'key') )? opts.key : 'shift';
var _keyReq = ( defined(opts, 'keyRequired') )? opts.keyRequired : false;

var _onEnabled = ( defined(opts, 'onEnabled') )? opts.onEnabled : function(){};
var _onDisabled = ( defined(opts, 'onDisabled') )? opts.onDisabled : function(){};
var _onDisabled = ( defined(opts, 'onDisabled') )? opts.onDisabled : function(){};
var _onChange = ( defined(opts, 'onChange') )? opts.onChange : function(){};

var _polystyle = ( defined(opts, 'polystyle') )? (JSON.parse(JSON.stringify(opts.polystyle))) : {};
var _hidePOI = ( defined(opts, 'hidePOI') )? opts.hidePOI : false;

var _keyDown = false;

if( !_map ){
console.log("We need to know the map");
return;
}

var _mapDiv = document.getElementById( _map.getDiv().getAttribute('id') );

if( _hidePOI ){

_map.poi = function(state){

var styles = [
Expand All @@ -96,11 +96,11 @@ function PolySnapper(opts){
this.set("styles", (state)? {} : styles );

}

}

if( _keyReq ){

var keymap = {
'shift': 16,
'ctrl': 17
Expand All @@ -115,7 +115,7 @@ function PolySnapper(opts){
_keyDown = (e.which == which)? false : true;
});
}

return {
polygon: function(){
return that.currentpoly;
Expand All @@ -124,16 +124,16 @@ function PolySnapper(opts){
return that.drawing;
},
enable: function(){

that.drawing = true;

if( _hidePOI ) _map.poi(false);

var vertexMarker = _marker;
var snapable_polys = that.polys.filter( function(p){ return ( typeof p.snapable !== 'undefined' && p.snapable ) } );
var snapable_points = snapable_polys.map( function(p){ return p.getPath().getArray() } ).reduce(function(a,b){ return a.concat(b) }, []);
var last_closeby = null;

//the official Drawing Manager will not work!
_map.setOptions({draggableCursor:'crosshair'});

Expand All @@ -150,12 +150,12 @@ function PolySnapper(opts){

});

//you can delete vertices in the current polygon by right clicking them
//you can delete vertices in the current polygon by right clicking them
_map.addListener("click", function(e){

// Because path is an MVCArray, we can simply append a new coordinate
// and it will automatically appear.
var ll = (last_closeby && (!_keyReq || _keyReq && _keyDown) )? last_closeby : e.latLng;
var ll = (last_closeby && (!_keyReq || _keyReq && _keyDown) )? last_closeby : e.latLng;
that.currentpoly.getPath().push(ll);
_onChange();

Expand All @@ -177,7 +177,7 @@ function PolySnapper(opts){
_onChange();
});
}());

//Same comments go for insert_at ...
(function insertAtRecurse(){
google.maps.event.addListenerOnce(currentpoly.getPath(), "insert_at", function(idx){
Expand All @@ -187,16 +187,16 @@ function PolySnapper(opts){
});
}());


/*
we cannot listen to move events on the gmap object.. because when we
drag existing points, or new ones, the mouse move events are suspended
instead, we must attach mousemove to the mapcanvas (jquery), and then
instead, we must attach mousemove to the mapcanvas (jquery), and then
convert x,y coordinates in the map canvas to lat lng points.
*/

_mapDiv.onmousemove = function(e){

bounds = _map.getBounds();
neLatlng = bounds.getNorthEast();
swLatlng = bounds.getSouthWest();
Expand All @@ -205,19 +205,37 @@ function PolySnapper(opts){
endLat = swLatlng.lat();
startLng = swLatlng.lng();

lat = startLat + (( e.offsetY/ this.offsetHeight ) * (endLat - startLat));
lng = startLng + (( e.offsetX/ this.offsetWidth ) * (endLng - startLng));
fullscreenMode = function () {
//Verifies if map is in fullscreen mode. If so, its size will match window's size
if ($(_map.getDiv()).children().eq(0).height() == window.innerHeight &&
$(_map.getDiv()).children().eq(0).width() == window.innerWidth) {
return true;
}
else {
return false;
}
}

if (fullscreenMode()) {
// If is in fullscreen mode, use windows's dimensions to scale
lat = startLat + ((e.offsetY / window.innerHeight) * (endLat - startLat));
lng = startLng + ((e.offsetX / window.innerWidth) * (endLng - startLng));
} else {
// If is not in fullscreen mode, use div's dimensions to scale
lat = startLat + ((e.offsetY / this.offsetHeight) * (endLat - startLat));
lng = startLng + ((e.offsetX / this.offsetWidth) * (endLng - startLng));
}

var ll = new google.maps.LatLng(lat, lng);

//find any of the existing polygon points are close to the mousepointer
var closeby = snapable_points.filter ( function(p){
return ( google.maps.geometry.spherical.computeDistanceBetween(ll, p) ) < _thresh
var closeby = snapable_points.filter ( function(p){
return ( google.maps.geometry.spherical.computeDistanceBetween(ll, p) ) < _thresh
})[0] || null;

/* we could just use:

if(closeby){
if(closeby){
vertexMarker.setOptions({
position: closeby,
map: map
Expand All @@ -232,7 +250,7 @@ function PolySnapper(opts){

*/

if(closeby && closeby != last_closeby){
if(closeby && closeby != last_closeby){
last_closeby = closeby;
vertexMarker.setPosition(closeby);
vertexMarker.setMap(_map);
Expand All @@ -244,18 +262,18 @@ function PolySnapper(opts){


};

//now execute the callback
_onEnabled();
},
disable: function(){

if(_hidePOI) _map.poi(true);

that.drawing = false;
_map.setOptions({draggableCursor:null});
that.currentpoly.setMap(null);

_mapDiv.onmousemove = null;

if(_keyReq){
Expand All @@ -269,7 +287,7 @@ function PolySnapper(opts){
_onDisabled();

}

}
}

}