3 my $field = $opt{'field'};
4 my $id = $opt{'id'} || $opt{'field'};
5 my $div_id = "div_$id";
7 my $vertices_json = $opt{'curr_value'} || '[]';
9 my $apikey = FS::Conf->new->config('google_maps_api_key');
12 <& hidden.html, %opt &>
13 <div id="<% $div_id %>" style="height: 600px; width: 600px"></div>
14 <div id="<% $div_id %>_hint" style="width: 100%; border: 2px solid black; text-align: center; box-sizing: border-box; padding: 4px"> </div>
16 <script src="<% $fsurl %>elements/jquery.js"></script>
17 <script src="https://maps.googleapis.com/maps/api/js?libraries=drawing&v=3.22<% $apikey ? "&key=$apikey" : '' %>"></script>
22 function updateFormInput(event) {
23 var path = window.polygon.getPath();
24 var vertices = []; // array of arrays, geoJSON style
25 for (var i =0; i < path.getLength(); i++) {
26 var xy = path.getAt(i);
27 vertices[i] = [ xy.lat(), xy.lng() ];
29 if (console) console.log(vertices); //XXX
30 $('#<% $field %>').prop('value', JSON.stringify(vertices));
36 center: {lat: 39.40114, lng: -96.57127}, // continental U.S.
37 mapTypeId: google.maps.MapTypeId.ROADMAP,
40 streetViewControl: false,
42 var div_map = $('#<% $div_id %>');
43 var div_hint = $('#<% $div_id %>_hint');
44 map = new google.maps.Map(div_map[0], mapOptions);
46 var set_hint = function(txt) {
50 var polygonComplete = function(p) {
53 drawingManager.setDrawingMode(null);
54 drawingManager.setOptions({ drawingControl: false });
56 // double click to delete a vertex (so long as it remains a polygon)
57 p.addListener('dblclick', function (mev) {
58 if (mev.vertex != null && window.polygon.getPath().length > 3) {
59 p.getPath().removeAt(mev.vertex);
62 // any time the polygon is modified, update the vertex list
63 p.getPath().addListener('set_at', updateFormInput);
64 p.getPath().addListener('insert_at', updateFormInput);
65 p.getPath().addListener('remove_at', updateFormInput);
70 set_hint('Edit the zone by dragging the markers. Double-click to remove a vertex.');
74 var polygonOptions = {
77 strokeColor: '#0000a0',
85 var vertex_array = <% $vertices_json %>;
86 if ( vertex_array.length > 2 ) {
87 // then we already have a polygon. make it acceptable to google maps,
88 // and also create a bounding box for it and fit the map to that.
91 var bounds = new google.maps.LatLngBounds();
92 for (var i = 0; i < vertex_array.length; i++) {
93 var xy = new google.maps.LatLng(vertex_array[i][0], vertex_array[i][1]);
98 polygonOptions.paths = [ path ];
99 polygonComplete(new google.maps.Polygon(polygonOptions));
100 map.fitBounds(bounds);
103 // there are no vertices, or not enough to make a polygon, so
104 // enable drawing mode to create a new one
106 drawingManager = new google.maps.drawing.DrawingManager({
107 drawingMode: google.maps.drawing.OverlayType.POLYGON,
108 drawingControl: true,
109 drawingControlOptions: {
110 position: google.maps.ControlPosition.TOP_CENTER,
112 google.maps.drawing.OverlayType.POLYGON,
115 polygonOptions: polygonOptions,
118 // after a single polygon is drawn: remember it, add a listener to let
119 // nodes be deleted, and exit drawing mode
120 drawingManager.addListener('polygoncomplete', polygonComplete);
121 drawingManager.setMap(map);
123 // center the map on the user (for lack of a better choice)
124 if (navigator.geolocation) {
125 navigator.geolocation.getCurrentPosition(function(position) {
127 lat: position.coords.latitude,
128 lng: position.coords.longitude
134 } // on error, or if geolocation isn't available, do nothing
136 set_hint('Click to place the corners of the zone.');