062aa48e838cc8e0c6c6f985958683813d4550a7
[freeside.git] / httemplate / elements / polygon.html
1 <%init>
2 my %opt = @_;
3 my $field = $opt{'field'};
4 my $id = $opt{'id'} || $opt{'field'};
5 my $div_id = "div_$id";
6
7 my $vertices_json = $opt{'curr_value'} || '[]';
8 </%init>
9 <& hidden.html, %opt &>
10 <div id="<% $div_id %>" style="height: 600px; width: 600px"></div>
11
12 <script src="<% $fsurl %>elements/jquery.js"></script>
13 <script src="https://maps.googleapis.com/maps/api/js?libraries=drawing&v=2"></script>
14 <script>
15 var map;
16 var drawingManager;
17
18 function updateFormInput(event) {
19   var path = window.polygon.getPath();
20   var vertices = []; // array of arrays, geoJSON style
21   for (var i =0; i < path.getLength(); i++) {
22     var xy = path.getAt(i);
23     vertices[i] = [ xy.lat(), xy.lng() ];
24   }
25   if (console) console.log(vertices); //XXX
26   $('#<% $field %>').prop('value', JSON.stringify(vertices));
27 }
28
29 $(function() {
30   mapOptions = {
31     zoom: 4,
32     center: {lat: 39.40114, lng: -96.57127}, // continental U.S.
33     mapTypeId: google.maps.MapTypeId.ROADMAP,
34     panControl: true,
35     scaleControl: true,
36     streetViewControl: false,
37   };
38   map = new google.maps.Map($('#<% $div_id %>')[0], mapOptions);
39
40   var polygonComplete = function(p) {
41     window.polygon = p;
42     if (drawingManager) {
43       drawingManager.setDrawingMode(null);
44       drawingManager.setOptions({ drawingControl: false });
45     }
46     // double click to delete a vertex (so long as it remains a polygon)
47     p.addListener('dblclick', function (mev) {
48       if (mev.vertex != null && window.polygon.getPath().length > 3) {
49         p.getPath().removeAt(mev.vertex);
50       }
51     });
52     // any time the polygon is modified, update the vertex list
53     p.getPath().addListener('set_at', updateFormInput);
54     p.getPath().addListener('insert_at', updateFormInput);
55     p.getPath().addListener('remove_at', updateFormInput);
56
57     // and also now
58     updateFormInput();
59   };
60
61   var polygonOptions = {
62     fillColor: '#0000a0',
63     fillOpacity: 0.2,
64     strokeColor: '#0000a0',
65     strokeWeight: 2,
66     clickable: false,
67     editable: true,
68     zIndex: 1,
69     map: map,
70   };
71
72   var vertex_array = <% $vertices_json %>;
73   if ( vertex_array.length > 2 ) {
74     // then we already have a polygon. make it acceptable to google maps,
75     // and also create a bounding box for it and fit the map to that.
76
77     var path = [];
78     var bounds = new google.maps.LatLngBounds();
79     for (var i = 0; i < vertex_array.length; i++) {
80       var xy = new google.maps.LatLng(vertex_array[i][0], vertex_array[i][1]);
81       path.push(xy);
82       bounds.extend(xy);
83     }
84
85     polygonOptions.paths = [ path ];
86     polygonComplete(new google.maps.Polygon(polygonOptions));
87     map.fitBounds(bounds);
88
89   } else {
90     // there are no vertices, or not enough to make a polygon, so 
91     // enable drawing mode to create a new one
92
93     drawingManager = new google.maps.drawing.DrawingManager({
94       drawingMode: google.maps.drawing.OverlayType.POLYGON,
95       drawingControl: true,
96       drawingControlOptions: {
97         position: google.maps.ControlPosition.TOP_CENTER,
98         drawingModes: [
99           google.maps.drawing.OverlayType.POLYGON,
100         ]
101       },
102       polygonOptions: polygonOptions,
103     });
104
105     // after a single polygon is drawn: remember it, add a listener to let
106     // nodes be deleted, and exit drawing mode
107     drawingManager.addListener('polygoncomplete', polygonComplete);
108     drawingManager.setMap(map);
109
110     // center the map on the user (for lack of a better choice)
111     if (navigator.geolocation) {
112       navigator.geolocation.getCurrentPosition(function(position) {
113         var pos = {
114           lat: position.coords.latitude,
115           lng: position.coords.longitude
116         };
117
118         map.setCenter(pos);
119         map.setZoom(12);
120       });
121     } // on error, or if geolocation isn't available, do nothing
122   }
123
124 });
125
126     </script>
127   </body>
128 </html>