/** * @file * GMap Shapes * GMap API version / Base case * * @NOTE This code now depends in various places, on the google.maps.geometry library. * 1. points encoding/decoding * 2. spherical distance calculations * If this library isn't loaded then YOU WILL GET SILENT FAILURE. There should be some kind * of user warning here, if the geometry library hasn't been loaded. I am not sure what the * gmaps convention for such reporting is? is a console.debug acceptable? * Note that you can specify to add the geometry library at the php side of things using hook_gmap() */ /*global $, Drupal, google.maps, !google.maps.geometry! */ Drupal.gmap.addHandler('gmap', function (elem) { var obj = this; // prepare and build a google.maps shape object obj.bind('prepareshape', function (shape) { var pa, cargs, style fillstyle; fillstyle = false; // does this shape have a fill option? cargs = {}; pa = []; // point array (array of LatLng-objects) // positioning determination switch (shape.type) { case 'circle': if ( typeof shape.center === 'array') { shape.center = new google.maps.LatLng(shape.center[0], shape.center[1]); } // otherwise it should be a LatLng already if ( shape.point2 ) { if ( typeof shape.point2 === 'array') { shape.point2 = new google.maps.LatLng(shape.point2[0], shape.point2[1]); } // otherwise it should be a LatLng already shape.radius = (google.maps.geometry) ? google.maps.geometry.spherical.computeDistanceBetween( shape.center, shape.point2 ) : 250; } // if you didn't pass a shape.point2, then you should have passed a shape.radius in meters break; case 'rpolygon': /* this is deprecated as we have circle now. It is left for backwards compatibility */ if ( typeof shape.center === 'array') { shape.center = new google.maps.LatLng(shape.center[0], shape.center[1]); } // otherwise it should be a LatLng already if ( typeof shape.point2 === 'array') { shape.point2 = new google.maps.LatLng(shape.point2[0], shape.point2[1]); } // otherwise it should be a LatLng already shape.radius = (google.maps.geometry) ? google.maps.geometry.spherical.computeDistanceBetween( shape.center, shape.point2 ) : 250; if ( !shape.numpoints ) { shape.numpoints = 20; } pa = obj.poly.calcPolyPoints(shape.center, radius, shape.numpoints); break; case 'polygon': fillstyle = true; case 'line': $.each(shape.points, function (i, n) { if ( typeof n === 'array') { n = new google.maps.LatLng(n[0], n[1]); } // otherwise it should be a LatLng already pa.push( n ); }); break; case 'encoded_polygon': fillstyle = true; case 'encoded_line': pa = ( google.maps.geometry ) ? google.maps.geometry.encoding.decodePath(shape.path) : []; // this trinary prevents errors if the google.maps gemoetry library wasn't loaded break; } /** * the shapes.style processing is a leftover from the gmaps v2 * code, and the shapes configuration system, from the php side * of things. */ if (shape.style) { if (typeof shape.style === 'string') { // the style is an index for one of our vars.styles if (obj.vars.styles[shape.style]) { style = obj.vars.styles[shape.style].slice(); // copy the array } } else { style = shape.style.slice(); // copy that array } style[0] = '#' + style[0]; // color style[1] = Number(style[1]); // strokewidth style[2] = style[2] / 100; // strokeOpacity if (fillstyle) { style[3] = '#' + style[3]; // fill colour style[4] = style[4] / 100; // fill opacity } if (shape.type == 'encoded_line') { shape.color = style[0]; shape.weight = style[1]; shape.opacity = style[2]; } else if (shape.type == 'encoded_polygon') { if ( shape.polylines ) { $.each(shape.polylines, function(i, polyline) { polyline.color = style[0]; polyline.weight = style[1]; polyline.opacity = style[2]; }); } shape.fill = true; shape.color = style[3]; shape.opacity = style[4]; shape.outline = true; } } // add any options to the configuration if (shape.opts) { $.extend(cargs, shape.opts); } /** * In general: (inherited concepts. If you change these, make sure you check them on the php side of things) * shape.color : color used for line and fill * shape.weight : stroke weight in pixels * shape.opacity : fill/stroke opacity in decimal value (0< opactity <1) * shape.fill : boolean direction to fill the shape */ // build the shape with options switch (shape.type) { case 'circle': cargs = {center:shape.center, radius: shape.radius, strokeColor: shape.color }; // required arges if ( shape.color ) { cargs.strokeColor = shape.color; } // outline color if ( shape.weight ) { cargs.strokeWeight = shape.weight; } // boundary line weight if ( shape.fill ) { cargs.fillColor = shape.color; } // shape fill color if ( shape.opacity ) { cargs.strokeOpacity = shape.opacity; cargs.fillOpacity = shape.opacity; } // shape opacity shape.shape = new google.maps.Circle(cargs); break; case 'rpolygon': case 'encoded_polygon': case 'polygon': cargs = { path: pa }; // required args if ( shape.outline ) { cargs.strokeColor = shape.color; } if ( shape.weight ) { cargs.strokeWeight = shape.weight; } if ( shape.fill ) { cargs.fillColor = shape.color; } if ( shape.opacity ) { cargs.strokeOpacity = shape.opacity; cargs.fillOpacity = shape.opacity; } shape.shape = new google.maps.Polygon(cargs); break; case 'line': case 'encoded_line': cargs = { path: pa }; // required args if ( shape.color ) { cargs.strokeColor = shape.color; } if ( shape.weight ) { cargs.strokeWeight = shape.weight; } if ( shape.opacity ) { cargs.strokeOpacity = shape.opacity; } shape.shape = new google.maps.Polyline(cargs); break; } }); // add a prepared shape to the map obj.bind('addshape', function (shape) { if (!obj.vars.shapes) { obj.vars.shapes = []; } obj.vars.shapes.push(shape); shape.shape.setMap(obj.map); if (obj.vars.behavior.clickableshapes) { google.maps.event.addListener(shape.shape, 'click', function () { obj.change('clickshape', -1, shape); }); } if (obj.vars.behavior.shapesextraevents) { google.maps.event.addListener(shape.shape, 'dblclick', function () { obj.change('dblclickshape', -1, shape); }); google.maps.event.addListener(shape.shape, 'mousedown', function () { obj.change('mousedownshape', -1, shape); }); google.maps.event.addListener(shape.shape, 'mouseout', function () { obj.change('mouseoutshape', -1, shape); }); google.maps.event.addListener(shape.shape, 'mouseover', function () { obj.change('mouseovershape', -1, shape); }); google.maps.event.addListener(shape.shape, 'mouseup', function () { obj.change('mouseupshape', -1, shape); }); google.maps.event.addListener(shape.shape, 'mousemove', function () { obj.change('mousemoveshape', -1, shape); }); google.maps.event.addListener(shape.shape, 'rightclick', function () { obj.change('rightclickshape', -1, shape); }); } }); obj.bind('delshape', function (shape) { shape.shape.setMap( null ); }); obj.bind('clearshapes', function () { if (obj.vars.shapes) { $.each(obj.vars.shapes, function (i, n) { obj.change('delshape', -1, n); }); } }); });