1332 lines
64 KiB
HTML
1332 lines
64 KiB
HTML
<!DOCTYPE html>
|
||
|
||
<html>
|
||
<head>
|
||
<title>view.map.js</title>
|
||
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
|
||
<meta name="viewport" content="width=device-width, target-densitydpi=160dpi, initial-scale=1.0; maximum-scale=1.0; user-scalable=0;">
|
||
<link rel="stylesheet" media="all" href="docco.css" />
|
||
</head>
|
||
<body>
|
||
<div id="container">
|
||
<div id="background"></div>
|
||
|
||
<ul id="jump_to">
|
||
<li>
|
||
<a class="large" href="javascript:void(0);">Jump To …</a>
|
||
<a class="small" href="javascript:void(0);">+</a>
|
||
<div id="jump_wrapper">
|
||
<div id="jump_page_wrapper">
|
||
<div id="jump_page">
|
||
|
||
|
||
<a class="source" href="backend.dataproxy.html">
|
||
backend.dataproxy.js
|
||
</a>
|
||
|
||
|
||
<a class="source" href="backend.memory.html">
|
||
backend.memory.js
|
||
</a>
|
||
|
||
|
||
<a class="source" href="ecma-fixes.html">
|
||
ecma-fixes.js
|
||
</a>
|
||
|
||
|
||
<a class="source" href="model.html">
|
||
model.js
|
||
</a>
|
||
|
||
|
||
<a class="source" href="view.flot.html">
|
||
view.flot.js
|
||
</a>
|
||
|
||
|
||
<a class="source" href="view.graph.html">
|
||
view.graph.js
|
||
</a>
|
||
|
||
|
||
<a class="source" href="view.grid.html">
|
||
view.grid.js
|
||
</a>
|
||
|
||
|
||
<a class="source" href="view.map.html">
|
||
view.map.js
|
||
</a>
|
||
|
||
|
||
<a class="source" href="view.multiview.html">
|
||
view.multiview.js
|
||
</a>
|
||
|
||
|
||
<a class="source" href="view.slickgrid.html">
|
||
view.slickgrid.js
|
||
</a>
|
||
|
||
|
||
<a class="source" href="view.timeline.html">
|
||
view.timeline.js
|
||
</a>
|
||
|
||
|
||
<a class="source" href="widget.facetviewer.html">
|
||
widget.facetviewer.js
|
||
</a>
|
||
|
||
|
||
<a class="source" href="widget.fields.html">
|
||
widget.fields.js
|
||
</a>
|
||
|
||
|
||
<a class="source" href="widget.filtereditor.html">
|
||
widget.filtereditor.js
|
||
</a>
|
||
|
||
|
||
<a class="source" href="widget.pager.html">
|
||
widget.pager.js
|
||
</a>
|
||
|
||
|
||
<a class="source" href="widget.queryeditor.html">
|
||
widget.queryeditor.js
|
||
</a>
|
||
|
||
|
||
<a class="source" href="widget.valuefilter.html">
|
||
widget.valuefilter.js
|
||
</a>
|
||
|
||
</div>
|
||
</div>
|
||
</li>
|
||
</ul>
|
||
|
||
<ul class="sections">
|
||
|
||
<li id="title">
|
||
<div class="annotation">
|
||
<h1>view.map.js</h1>
|
||
</div>
|
||
</li>
|
||
|
||
|
||
|
||
<li id="section-1">
|
||
<div class="annotation">
|
||
|
||
<div class="pilwrap ">
|
||
<a class="pilcrow" href="#section-1">¶</a>
|
||
</div>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre><span class="hljs-comment">/*jshint multistr:true */</span>
|
||
|
||
<span class="hljs-keyword">this</span>.recline = <span class="hljs-keyword">this</span>.recline || {};
|
||
<span class="hljs-keyword">this</span>.recline.View = <span class="hljs-keyword">this</span>.recline.View || {};
|
||
|
||
(<span class="hljs-function"><span class="hljs-keyword">function</span><span class="hljs-params">($, my)</span> </span>{
|
||
<span class="hljs-pi"> "use strict"</span>;</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-2">
|
||
<div class="annotation">
|
||
|
||
<div class="pilwrap ">
|
||
<a class="pilcrow" href="#section-2">¶</a>
|
||
</div>
|
||
<h2 id="map-view-for-a-dataset-using-leaflet-mapping-library-">Map view for a Dataset using Leaflet mapping library.</h2>
|
||
<p>This view allows to plot gereferenced records on a map. The location
|
||
information can be provided in 2 ways:</p>
|
||
<ol>
|
||
<li>Via a single field. This field must be either a geo_point or
|
||
<a href="http://geojson.org">GeoJSON</a> object</li>
|
||
<li>Via two fields with latitude and longitude coordinates.</li>
|
||
</ol>
|
||
<p>Which fields in the data these correspond to can be configured via the state
|
||
(and are guessed if no info is provided).</p>
|
||
<p>Initialization arguments are as standard for Dataset Views. State object may
|
||
have the following (optional) configuration options:</p>
|
||
<pre>
|
||
{
|
||
// geomField if specified will be used in preference to lat/lon
|
||
geomField: {id of field containing geometry in the dataset}
|
||
lonField: {id of field containing longitude in the dataset}
|
||
latField: {id of field containing latitude in the dataset}
|
||
autoZoom: true,
|
||
// use cluster support
|
||
// cluster: true = always on
|
||
// cluster: false = always off
|
||
cluster: false
|
||
}
|
||
</pre>
|
||
|
||
<p>Useful attributes to know about (if e.g. customizing)</p>
|
||
<ul>
|
||
<li>map: the Leaflet map (L.Map)</li>
|
||
<li>features: Leaflet GeoJSON layer containing all the features (L.GeoJSON)</li>
|
||
</ul>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre>my.Map = Backbone.View.extend({
|
||
template: <span class="hljs-string">' \
|
||
<div class="recline-map"> \
|
||
<div class="panel map"></div> \
|
||
</div> \
|
||
'</span>,</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-3">
|
||
<div class="annotation">
|
||
|
||
<div class="pilwrap ">
|
||
<a class="pilcrow" href="#section-3">¶</a>
|
||
</div>
|
||
<p>These are the default (case-insensitive) names of field that are used if found.
|
||
If not found, the user will need to define the fields via the editor.</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> latitudeFieldNames: [<span class="hljs-string">'lat'</span>,<span class="hljs-string">'latitude'</span>],
|
||
longitudeFieldNames: [<span class="hljs-string">'lon'</span>,<span class="hljs-string">'longitude'</span>],
|
||
geometryFieldNames: [<span class="hljs-string">'geojson'</span>, <span class="hljs-string">'geom'</span>,<span class="hljs-string">'the_geom'</span>,<span class="hljs-string">'geometry'</span>,<span class="hljs-string">'spatial'</span>,<span class="hljs-string">'location'</span>, <span class="hljs-string">'geo'</span>, <span class="hljs-string">'lonlat'</span>],
|
||
|
||
initialize: <span class="hljs-function"><span class="hljs-keyword">function</span><span class="hljs-params">(options)</span> </span>{
|
||
<span class="hljs-keyword">var</span> self = <span class="hljs-keyword">this</span>;
|
||
<span class="hljs-keyword">this</span>.visible = <span class="hljs-keyword">this</span>.$el.is(<span class="hljs-string">':visible'</span>);
|
||
<span class="hljs-keyword">this</span>.mapReady = <span class="hljs-literal">false</span>;</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-4">
|
||
<div class="annotation">
|
||
|
||
<div class="pilwrap ">
|
||
<a class="pilcrow" href="#section-4">¶</a>
|
||
</div>
|
||
<p>this will be the Leaflet L.Map object (setup below)</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> <span class="hljs-keyword">this</span>.map = <span class="hljs-literal">null</span>;
|
||
|
||
<span class="hljs-keyword">var</span> stateData = _.extend({
|
||
geomField: <span class="hljs-literal">null</span>,
|
||
lonField: <span class="hljs-literal">null</span>,
|
||
latField: <span class="hljs-literal">null</span>,
|
||
autoZoom: <span class="hljs-literal">true</span>,
|
||
cluster: <span class="hljs-literal">false</span>
|
||
},
|
||
options.state
|
||
);
|
||
<span class="hljs-keyword">this</span>.state = <span class="hljs-keyword">new</span> recline.Model.ObjectState(stateData);
|
||
|
||
<span class="hljs-keyword">this</span>._clusterOptions = {
|
||
zoomToBoundsOnClick: <span class="hljs-literal">true</span>,</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-5">
|
||
<div class="annotation">
|
||
|
||
<div class="pilwrap ">
|
||
<a class="pilcrow" href="#section-5">¶</a>
|
||
</div>
|
||
<p>disableClusteringAtZoom: 10,</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> maxClusterRadius: <span class="hljs-number">80</span>,
|
||
singleMarkerMode: <span class="hljs-literal">false</span>,
|
||
skipDuplicateAddTesting: <span class="hljs-literal">true</span>,
|
||
animateAddingMarkers: <span class="hljs-literal">false</span>
|
||
};</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-6">
|
||
<div class="annotation">
|
||
|
||
<div class="pilwrap ">
|
||
<a class="pilcrow" href="#section-6">¶</a>
|
||
</div>
|
||
<p>Listen to changes in the fields</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> <span class="hljs-keyword">this</span>.listenTo(<span class="hljs-keyword">this</span>.model.fields, <span class="hljs-string">'change'</span>, <span class="hljs-function"><span class="hljs-keyword">function</span><span class="hljs-params">()</span> </span>{
|
||
self._setupGeometryField();
|
||
self.render();
|
||
});</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-7">
|
||
<div class="annotation">
|
||
|
||
<div class="pilwrap ">
|
||
<a class="pilcrow" href="#section-7">¶</a>
|
||
</div>
|
||
<p>Listen to changes in the records</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> <span class="hljs-keyword">this</span>.listenTo(<span class="hljs-keyword">this</span>.model.records, <span class="hljs-string">'add'</span>, <span class="hljs-function"><span class="hljs-keyword">function</span><span class="hljs-params">(doc)</span></span>{self.redraw(<span class="hljs-string">'add'</span>,doc);});
|
||
<span class="hljs-keyword">this</span>.listenTo(<span class="hljs-keyword">this</span>.model.records, <span class="hljs-string">'change'</span>, <span class="hljs-function"><span class="hljs-keyword">function</span><span class="hljs-params">(doc)</span></span>{
|
||
self.redraw(<span class="hljs-string">'remove'</span>,doc);
|
||
self.redraw(<span class="hljs-string">'add'</span>,doc);
|
||
});
|
||
<span class="hljs-keyword">this</span>.listenTo(<span class="hljs-keyword">this</span>.model.records, <span class="hljs-string">'remove'</span>, <span class="hljs-function"><span class="hljs-keyword">function</span><span class="hljs-params">(doc)</span></span>{self.redraw(<span class="hljs-string">'remove'</span>,doc);});
|
||
<span class="hljs-keyword">this</span>.listenTo(<span class="hljs-keyword">this</span>.model.records, <span class="hljs-string">'reset'</span>, <span class="hljs-function"><span class="hljs-keyword">function</span><span class="hljs-params">()</span></span>{self.redraw(<span class="hljs-string">'reset'</span>);});
|
||
|
||
<span class="hljs-keyword">this</span>.menu = <span class="hljs-keyword">new</span> my.MapMenu({
|
||
model: <span class="hljs-keyword">this</span>.model,
|
||
state: <span class="hljs-keyword">this</span>.state.toJSON()
|
||
});
|
||
<span class="hljs-keyword">this</span>.listenTo(<span class="hljs-keyword">this</span>.menu.state, <span class="hljs-string">'change'</span>, <span class="hljs-function"><span class="hljs-keyword">function</span><span class="hljs-params">()</span> </span>{
|
||
self.state.set(self.menu.state.toJSON());
|
||
self.redraw();
|
||
});
|
||
<span class="hljs-keyword">this</span>.listenTo(<span class="hljs-keyword">this</span>.state, <span class="hljs-string">'change'</span>, <span class="hljs-function"><span class="hljs-keyword">function</span><span class="hljs-params">()</span> </span>{
|
||
self.redraw();
|
||
});
|
||
<span class="hljs-keyword">this</span>.elSidebar = <span class="hljs-keyword">this</span>.menu.$el;
|
||
},</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-8">
|
||
<div class="annotation">
|
||
|
||
<div class="pilwrap ">
|
||
<a class="pilcrow" href="#section-8">¶</a>
|
||
</div>
|
||
<h2 id="customization-functions">Customization Functions</h2>
|
||
<p>The following methods are designed for overriding in order to customize
|
||
behaviour</p>
|
||
|
||
</div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-9">
|
||
<div class="annotation">
|
||
|
||
<div class="pilwrap ">
|
||
<a class="pilcrow" href="#section-9">¶</a>
|
||
</div>
|
||
<h3 id="infobox">infobox</h3>
|
||
<p>Function to create infoboxes used in popups. The default behaviour is very simple and just lists all attributes.</p>
|
||
<p>Users should override this function to customize behaviour i.e.</p>
|
||
<pre><code>view = <span class="hljs-keyword">new</span> View({...});
|
||
view.infobox = <span class="hljs-function"><span class="hljs-keyword">function</span><span class="hljs-params">(record)</span> </span>{
|
||
...
|
||
}
|
||
</code></pre>
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> infobox: <span class="hljs-function"><span class="hljs-keyword">function</span><span class="hljs-params">(record)</span> </span>{
|
||
<span class="hljs-keyword">var</span> html = <span class="hljs-string">''</span>;
|
||
<span class="hljs-keyword">for</span> (<span class="hljs-keyword">var</span> key <span class="hljs-keyword">in</span> record.attributes){
|
||
<span class="hljs-keyword">if</span> (!(<span class="hljs-keyword">this</span>.state.get(<span class="hljs-string">'geomField'</span>) && key == <span class="hljs-keyword">this</span>.state.get(<span class="hljs-string">'geomField'</span>))){
|
||
html += <span class="hljs-string">'<div><strong>'</span> + key + <span class="hljs-string">'</strong>: '</span>+ record.attributes[key] + <span class="hljs-string">'</div>'</span>;
|
||
}
|
||
}
|
||
<span class="hljs-keyword">return</span> html;
|
||
},</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-10">
|
||
<div class="annotation">
|
||
|
||
<div class="pilwrap ">
|
||
<a class="pilcrow" href="#section-10">¶</a>
|
||
</div>
|
||
<p>Options to use for the <a href="http://leaflet.cloudmade.com/reference.html#geojson">Leaflet GeoJSON layer</a>
|
||
See also <a href="http://leaflet.cloudmade.com/examples/geojson.html">http://leaflet.cloudmade.com/examples/geojson.html</a></p>
|
||
<p>e.g.</p>
|
||
<pre><code>pointToLayer: <span class="hljs-function"><span class="hljs-keyword">function</span><span class="hljs-params">(feature, latLng)</span>
|
||
<span class="hljs-title">onEachFeature</span>: <span class="hljs-title">function</span><span class="hljs-params">(feature, layer)</span></span>
|
||
</code></pre><p>See defaults for examples</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> geoJsonLayerOptions: {</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-11">
|
||
<div class="annotation">
|
||
|
||
<div class="pilwrap ">
|
||
<a class="pilcrow" href="#section-11">¶</a>
|
||
</div>
|
||
<p>pointToLayer function to use when creating points</p>
|
||
<p>Default behaviour shown here is to create a marker using the
|
||
popupContent set on the feature properties (created via infobox function
|
||
during feature generation)</p>
|
||
<p>NB: inside pointToLayer <code>this</code> will be set to point to this map view
|
||
instance (which allows e.g. this.markers to work in this default case)</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> pointToLayer: <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-params">(feature, latlng)</span> </span>{
|
||
<span class="hljs-keyword">var</span> marker = <span class="hljs-keyword">new</span> L.Marker(latlng);
|
||
marker.bindPopup(feature.properties.popupContent);</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-12">
|
||
<div class="annotation">
|
||
|
||
<div class="pilwrap ">
|
||
<a class="pilcrow" href="#section-12">¶</a>
|
||
</div>
|
||
<p>this is for cluster case</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> <span class="hljs-keyword">this</span>.markers.addLayer(marker);
|
||
<span class="hljs-keyword">return</span> marker;
|
||
},</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-13">
|
||
<div class="annotation">
|
||
|
||
<div class="pilwrap ">
|
||
<a class="pilcrow" href="#section-13">¶</a>
|
||
</div>
|
||
<p>onEachFeature default which adds popup in</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> onEachFeature: <span class="hljs-function"><span class="hljs-keyword">function</span><span class="hljs-params">(feature, layer)</span> </span>{
|
||
<span class="hljs-keyword">if</span> (feature.properties && feature.properties.popupContent) {
|
||
layer.bindPopup(feature.properties.popupContent);
|
||
}
|
||
}
|
||
},</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-14">
|
||
<div class="annotation">
|
||
|
||
<div class="pilwrap ">
|
||
<a class="pilcrow" href="#section-14">¶</a>
|
||
</div>
|
||
<h2 id="end-customization-section">END: Customization section</h2>
|
||
|
||
</div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-15">
|
||
<div class="annotation">
|
||
|
||
<div class="pilwrap ">
|
||
<a class="pilcrow" href="#section-15">¶</a>
|
||
</div>
|
||
|
||
</div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-16">
|
||
<div class="annotation">
|
||
|
||
<div class="pilwrap ">
|
||
<a class="pilcrow" href="#section-16">¶</a>
|
||
</div>
|
||
<h3 id="public-adds-the-necessary-elements-to-the-page-">Public: Adds the necessary elements to the page.</h3>
|
||
<p>Also sets up the editor fields and the map if necessary.</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> render: <span class="hljs-function"><span class="hljs-keyword">function</span><span class="hljs-params">()</span> </span>{
|
||
<span class="hljs-keyword">var</span> self = <span class="hljs-keyword">this</span>;
|
||
<span class="hljs-keyword">var</span> htmls = Mustache.render(<span class="hljs-keyword">this</span>.template, <span class="hljs-keyword">this</span>.model.toTemplateJSON());
|
||
<span class="hljs-keyword">this</span>.$el.html(htmls);
|
||
<span class="hljs-keyword">this</span>.$map = <span class="hljs-keyword">this</span>.$el.find(<span class="hljs-string">'.panel.map'</span>);
|
||
<span class="hljs-keyword">this</span>.redraw();
|
||
<span class="hljs-keyword">return</span> <span class="hljs-keyword">this</span>;
|
||
},</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-17">
|
||
<div class="annotation">
|
||
|
||
<div class="pilwrap ">
|
||
<a class="pilcrow" href="#section-17">¶</a>
|
||
</div>
|
||
<h3 id="public-redraws-the-features-on-the-map-according-to-the-action-provided">Public: Redraws the features on the map according to the action provided</h3>
|
||
<p>Actions can be:</p>
|
||
<ul>
|
||
<li>reset: Clear all features</li>
|
||
<li>add: Add one or n features (records)</li>
|
||
<li>remove: Remove one or n features (records)</li>
|
||
<li>refresh: Clear existing features and add all current records</li>
|
||
</ul>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> redraw: <span class="hljs-function"><span class="hljs-keyword">function</span><span class="hljs-params">(action, doc)</span></span>{
|
||
<span class="hljs-keyword">var</span> self = <span class="hljs-keyword">this</span>;
|
||
action = action || <span class="hljs-string">'refresh'</span>;</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-18">
|
||
<div class="annotation">
|
||
|
||
<div class="pilwrap ">
|
||
<a class="pilcrow" href="#section-18">¶</a>
|
||
</div>
|
||
<p>try to set things up if not already</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> <span class="hljs-keyword">if</span> (!self._geomReady()){
|
||
self._setupGeometryField();
|
||
}
|
||
<span class="hljs-keyword">if</span> (!self.mapReady){
|
||
self._setupMap();
|
||
}
|
||
|
||
<span class="hljs-keyword">if</span> (<span class="hljs-keyword">this</span>._geomReady() && <span class="hljs-keyword">this</span>.mapReady){</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-19">
|
||
<div class="annotation">
|
||
|
||
<div class="pilwrap ">
|
||
<a class="pilcrow" href="#section-19">¶</a>
|
||
</div>
|
||
<p>removing ad re-adding the layer enables faster bulk loading</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> <span class="hljs-keyword">this</span>.map.removeLayer(<span class="hljs-keyword">this</span>.features);
|
||
<span class="hljs-keyword">this</span>.map.removeLayer(<span class="hljs-keyword">this</span>.markers);
|
||
|
||
<span class="hljs-keyword">var</span> countBefore = <span class="hljs-number">0</span>;
|
||
<span class="hljs-keyword">this</span>.features.eachLayer(<span class="hljs-function"><span class="hljs-keyword">function</span><span class="hljs-params">()</span></span>{countBefore++;});
|
||
|
||
<span class="hljs-keyword">if</span> (action == <span class="hljs-string">'refresh'</span> || action == <span class="hljs-string">'reset'</span>) {
|
||
<span class="hljs-keyword">this</span>.features.clearLayers();</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-20">
|
||
<div class="annotation">
|
||
|
||
<div class="pilwrap ">
|
||
<a class="pilcrow" href="#section-20">¶</a>
|
||
</div>
|
||
<p>recreate cluster group because of issues with clearLayer</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> <span class="hljs-keyword">this</span>.map.removeLayer(<span class="hljs-keyword">this</span>.markers);
|
||
<span class="hljs-keyword">this</span>.markers = <span class="hljs-keyword">new</span> L.MarkerClusterGroup(<span class="hljs-keyword">this</span>._clusterOptions);
|
||
<span class="hljs-keyword">this</span>._add(<span class="hljs-keyword">this</span>.model.records.models);
|
||
} <span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> (action == <span class="hljs-string">'add'</span> && doc){
|
||
<span class="hljs-keyword">this</span>._add(doc);
|
||
} <span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> (action == <span class="hljs-string">'remove'</span> && doc){
|
||
<span class="hljs-keyword">this</span>._remove(doc);
|
||
}</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-21">
|
||
<div class="annotation">
|
||
|
||
<div class="pilwrap ">
|
||
<a class="pilcrow" href="#section-21">¶</a>
|
||
</div>
|
||
<p>this must come before zooming!
|
||
if not: errors when using e.g. circle markers like
|
||
“Cannot call method ‘project’ of undefined”</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> <span class="hljs-keyword">if</span> (<span class="hljs-keyword">this</span>.state.get(<span class="hljs-string">'cluster'</span>)) {
|
||
<span class="hljs-keyword">this</span>.map.addLayer(<span class="hljs-keyword">this</span>.markers);
|
||
} <span class="hljs-keyword">else</span> {
|
||
<span class="hljs-keyword">this</span>.map.addLayer(<span class="hljs-keyword">this</span>.features);
|
||
}
|
||
|
||
<span class="hljs-keyword">if</span> (<span class="hljs-keyword">this</span>.state.get(<span class="hljs-string">'autoZoom'</span>)){
|
||
<span class="hljs-keyword">if</span> (<span class="hljs-keyword">this</span>.visible){
|
||
<span class="hljs-keyword">this</span>._zoomToFeatures();
|
||
} <span class="hljs-keyword">else</span> {
|
||
<span class="hljs-keyword">this</span>._zoomPending = <span class="hljs-literal">true</span>;
|
||
}
|
||
}
|
||
}
|
||
},
|
||
|
||
show: <span class="hljs-function"><span class="hljs-keyword">function</span><span class="hljs-params">()</span> </span>{</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-22">
|
||
<div class="annotation">
|
||
|
||
<div class="pilwrap ">
|
||
<a class="pilcrow" href="#section-22">¶</a>
|
||
</div>
|
||
<p>If the div was hidden, Leaflet needs to recalculate some sizes
|
||
to display properly</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> <span class="hljs-keyword">if</span> (<span class="hljs-keyword">this</span>.map){
|
||
<span class="hljs-keyword">this</span>.map.invalidateSize();
|
||
<span class="hljs-keyword">if</span> (<span class="hljs-keyword">this</span>._zoomPending && <span class="hljs-keyword">this</span>.state.get(<span class="hljs-string">'autoZoom'</span>)) {
|
||
<span class="hljs-keyword">this</span>._zoomToFeatures();
|
||
<span class="hljs-keyword">this</span>._zoomPending = <span class="hljs-literal">false</span>;
|
||
}
|
||
}
|
||
<span class="hljs-keyword">this</span>.visible = <span class="hljs-literal">true</span>;
|
||
},
|
||
|
||
hide: <span class="hljs-function"><span class="hljs-keyword">function</span><span class="hljs-params">()</span> </span>{
|
||
<span class="hljs-keyword">this</span>.visible = <span class="hljs-literal">false</span>;
|
||
},
|
||
|
||
_geomReady: <span class="hljs-function"><span class="hljs-keyword">function</span><span class="hljs-params">()</span> </span>{
|
||
<span class="hljs-keyword">return</span> <span class="hljs-built_in">Boolean</span>(<span class="hljs-keyword">this</span>.state.get(<span class="hljs-string">'geomField'</span>) || (<span class="hljs-keyword">this</span>.state.get(<span class="hljs-string">'latField'</span>) && <span class="hljs-keyword">this</span>.state.get(<span class="hljs-string">'lonField'</span>)));
|
||
},</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-23">
|
||
<div class="annotation">
|
||
|
||
<div class="pilwrap ">
|
||
<a class="pilcrow" href="#section-23">¶</a>
|
||
</div>
|
||
<p>Private: Add one or n features to the map</p>
|
||
<p>For each record passed, a GeoJSON geometry will be extracted and added
|
||
to the features layer. If an exception is thrown, the process will be
|
||
stopped and an error notification shown.</p>
|
||
<p>Each feature will have a popup associated with all the record fields.</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> _add: <span class="hljs-function"><span class="hljs-keyword">function</span><span class="hljs-params">(docs)</span></span>{
|
||
<span class="hljs-keyword">var</span> self = <span class="hljs-keyword">this</span>;
|
||
|
||
<span class="hljs-keyword">if</span> (!(docs <span class="hljs-keyword">instanceof</span> <span class="hljs-built_in">Array</span>)) docs = [docs];
|
||
|
||
<span class="hljs-keyword">var</span> count = <span class="hljs-number">0</span>;
|
||
<span class="hljs-keyword">var</span> wrongSoFar = <span class="hljs-number">0</span>;
|
||
_.every(docs, <span class="hljs-function"><span class="hljs-keyword">function</span><span class="hljs-params">(doc)</span></span>{
|
||
count += <span class="hljs-number">1</span>;
|
||
<span class="hljs-keyword">var</span> feature = self._getGeometryFromRecord(doc);
|
||
<span class="hljs-keyword">if</span> (<span class="hljs-keyword">typeof</span> feature === <span class="hljs-string">'undefined'</span> || feature === <span class="hljs-literal">null</span>){</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-24">
|
||
<div class="annotation">
|
||
|
||
<div class="pilwrap ">
|
||
<a class="pilcrow" href="#section-24">¶</a>
|
||
</div>
|
||
<p>Empty field</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> <span class="hljs-keyword">return</span> <span class="hljs-literal">true</span>;
|
||
} <span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> (feature <span class="hljs-keyword">instanceof</span> <span class="hljs-built_in">Object</span>){
|
||
feature.properties = {
|
||
popupContent: self.infobox(doc),</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-25">
|
||
<div class="annotation">
|
||
|
||
<div class="pilwrap ">
|
||
<a class="pilcrow" href="#section-25">¶</a>
|
||
</div>
|
||
<p>Add a reference to the model id, which will allow us to
|
||
link this Leaflet layer to a Recline doc</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> cid: doc.cid
|
||
};
|
||
|
||
<span class="hljs-keyword">try</span> {
|
||
self.features.addData(feature);
|
||
} <span class="hljs-keyword">catch</span> (except) {
|
||
wrongSoFar += <span class="hljs-number">1</span>;
|
||
<span class="hljs-keyword">var</span> msg = <span class="hljs-string">'Wrong geometry value'</span>;
|
||
<span class="hljs-keyword">if</span> (except.message) msg += <span class="hljs-string">' ('</span> + except.message + <span class="hljs-string">')'</span>;
|
||
<span class="hljs-keyword">if</span> (wrongSoFar <= <span class="hljs-number">10</span>) {
|
||
self.trigger(<span class="hljs-string">'recline:flash'</span>, {message: msg, category:<span class="hljs-string">'error'</span>});
|
||
}
|
||
}
|
||
} <span class="hljs-keyword">else</span> {
|
||
wrongSoFar += <span class="hljs-number">1</span>;
|
||
<span class="hljs-keyword">if</span> (wrongSoFar <= <span class="hljs-number">10</span>) {
|
||
self.trigger(<span class="hljs-string">'recline:flash'</span>, {message: <span class="hljs-string">'Wrong geometry value'</span>, category:<span class="hljs-string">'error'</span>});
|
||
}
|
||
}
|
||
<span class="hljs-keyword">return</span> <span class="hljs-literal">true</span>;
|
||
});
|
||
},</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-26">
|
||
<div class="annotation">
|
||
|
||
<div class="pilwrap ">
|
||
<a class="pilcrow" href="#section-26">¶</a>
|
||
</div>
|
||
<p>Private: Remove one or n features from the map</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> _remove: <span class="hljs-function"><span class="hljs-keyword">function</span><span class="hljs-params">(docs)</span></span>{
|
||
|
||
<span class="hljs-keyword">var</span> self = <span class="hljs-keyword">this</span>;
|
||
|
||
<span class="hljs-keyword">if</span> (!(docs <span class="hljs-keyword">instanceof</span> <span class="hljs-built_in">Array</span>)) docs = [docs];
|
||
|
||
_.each(docs,<span class="hljs-function"><span class="hljs-keyword">function</span><span class="hljs-params">(doc)</span></span>{
|
||
<span class="hljs-keyword">for</span> (<span class="hljs-keyword">var</span> key <span class="hljs-keyword">in</span> self.features._layers){
|
||
<span class="hljs-keyword">if</span> (self.features._layers[key].feature.geometry.properties.cid == doc.cid){
|
||
self.features.removeLayer(self.features._layers[key]);
|
||
}
|
||
}
|
||
});
|
||
|
||
},</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-27">
|
||
<div class="annotation">
|
||
|
||
<div class="pilwrap ">
|
||
<a class="pilcrow" href="#section-27">¶</a>
|
||
</div>
|
||
<p>Private: convert DMS coordinates to decimal</p>
|
||
<p>north and east are positive, south and west are negative</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> _parseCoordinateString: <span class="hljs-function"><span class="hljs-keyword">function</span><span class="hljs-params">(coord)</span></span>{
|
||
<span class="hljs-keyword">if</span> (<span class="hljs-keyword">typeof</span>(coord) != <span class="hljs-string">'string'</span>) {
|
||
<span class="hljs-keyword">return</span>(<span class="hljs-built_in">parseFloat</span>(coord));
|
||
}
|
||
<span class="hljs-keyword">var</span> dms = coord.split(<span class="hljs-regexp">/[^-?\.\d\w]+/</span>);
|
||
<span class="hljs-keyword">var</span> deg = <span class="hljs-number">0</span>; <span class="hljs-keyword">var</span> m = <span class="hljs-number">0</span>;
|
||
<span class="hljs-keyword">var</span> toDeg = [<span class="hljs-number">1</span>, <span class="hljs-number">60</span>, <span class="hljs-number">3600</span>]; <span class="hljs-comment">// conversion factors for Deg, min, sec</span>
|
||
<span class="hljs-keyword">var</span> i;
|
||
<span class="hljs-keyword">for</span> (i = <span class="hljs-number">0</span>; i < dms.length; ++i) {
|
||
<span class="hljs-keyword">if</span> (<span class="hljs-built_in">isNaN</span>(<span class="hljs-built_in">parseFloat</span>(dms[i]))) {
|
||
<span class="hljs-keyword">continue</span>;
|
||
}
|
||
deg += <span class="hljs-built_in">parseFloat</span>(dms[i]) / toDeg[m];
|
||
m += <span class="hljs-number">1</span>;
|
||
}
|
||
<span class="hljs-keyword">if</span> (coord.match(<span class="hljs-regexp">/[SW]/</span>)) {
|
||
deg = -<span class="hljs-number">1</span>*deg;
|
||
}
|
||
<span class="hljs-keyword">return</span>(deg);
|
||
},</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-28">
|
||
<div class="annotation">
|
||
|
||
<div class="pilwrap ">
|
||
<a class="pilcrow" href="#section-28">¶</a>
|
||
</div>
|
||
<p>Private: Return a GeoJSON geomtry extracted from the record fields</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> _getGeometryFromRecord: <span class="hljs-function"><span class="hljs-keyword">function</span><span class="hljs-params">(doc)</span></span>{
|
||
<span class="hljs-keyword">if</span> (<span class="hljs-keyword">this</span>.state.get(<span class="hljs-string">'geomField'</span>)){
|
||
<span class="hljs-keyword">var</span> value = doc.get(<span class="hljs-keyword">this</span>.state.get(<span class="hljs-string">'geomField'</span>));
|
||
<span class="hljs-keyword">if</span> (<span class="hljs-keyword">typeof</span>(value) === <span class="hljs-string">'string'</span>){</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-29">
|
||
<div class="annotation">
|
||
|
||
<div class="pilwrap ">
|
||
<a class="pilcrow" href="#section-29">¶</a>
|
||
</div>
|
||
<p>We <em>may</em> have a GeoJSON string representation</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> <span class="hljs-keyword">try</span> {
|
||
value = $.parseJSON(value);
|
||
} <span class="hljs-keyword">catch</span>(e) {}
|
||
}
|
||
<span class="hljs-keyword">if</span> (<span class="hljs-keyword">typeof</span>(value) === <span class="hljs-string">'string'</span>) {
|
||
value = value.replace(<span class="hljs-string">'('</span>, <span class="hljs-string">''</span>).replace(<span class="hljs-string">')'</span>, <span class="hljs-string">''</span>);
|
||
<span class="hljs-keyword">var</span> parts = value.split(<span class="hljs-string">','</span>);
|
||
<span class="hljs-keyword">var</span> lat = <span class="hljs-keyword">this</span>._parseCoordinateString(parts[<span class="hljs-number">0</span>]);
|
||
<span class="hljs-keyword">var</span> lon = <span class="hljs-keyword">this</span>._parseCoordinateString(parts[<span class="hljs-number">1</span>]);
|
||
|
||
<span class="hljs-keyword">if</span> (!<span class="hljs-built_in">isNaN</span>(lon) && !<span class="hljs-built_in">isNaN</span>(<span class="hljs-built_in">parseFloat</span>(lat))) {
|
||
<span class="hljs-keyword">return</span> {
|
||
<span class="hljs-string">"type"</span>: <span class="hljs-string">"Point"</span>,
|
||
<span class="hljs-string">"coordinates"</span>: [lon, lat]
|
||
};
|
||
} <span class="hljs-keyword">else</span> {
|
||
<span class="hljs-keyword">return</span> <span class="hljs-literal">null</span>;
|
||
}
|
||
} <span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> (value && _.isArray(value)) {</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-30">
|
||
<div class="annotation">
|
||
|
||
<div class="pilwrap ">
|
||
<a class="pilcrow" href="#section-30">¶</a>
|
||
</div>
|
||
<p>[ lon, lat ]</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> <span class="hljs-keyword">return</span> {
|
||
<span class="hljs-string">"type"</span>: <span class="hljs-string">"Point"</span>,
|
||
<span class="hljs-string">"coordinates"</span>: [value[<span class="hljs-number">0</span>], value[<span class="hljs-number">1</span>]]
|
||
};
|
||
} <span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> (value && value.lat) {</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-31">
|
||
<div class="annotation">
|
||
|
||
<div class="pilwrap ">
|
||
<a class="pilcrow" href="#section-31">¶</a>
|
||
</div>
|
||
<p>of form { lat: …, lon: …}</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> <span class="hljs-keyword">return</span> {
|
||
<span class="hljs-string">"type"</span>: <span class="hljs-string">"Point"</span>,
|
||
<span class="hljs-string">"coordinates"</span>: [value.lon || value.lng, value.lat]
|
||
};
|
||
}</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-32">
|
||
<div class="annotation">
|
||
|
||
<div class="pilwrap ">
|
||
<a class="pilcrow" href="#section-32">¶</a>
|
||
</div>
|
||
<p>We o/w assume that contents of the field are a valid GeoJSON object</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> <span class="hljs-keyword">return</span> value;
|
||
} <span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> (<span class="hljs-keyword">this</span>.state.get(<span class="hljs-string">'lonField'</span>) && <span class="hljs-keyword">this</span>.state.get(<span class="hljs-string">'latField'</span>)){</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-33">
|
||
<div class="annotation">
|
||
|
||
<div class="pilwrap ">
|
||
<a class="pilcrow" href="#section-33">¶</a>
|
||
</div>
|
||
<p>We’ll create a GeoJSON like point object from the two lat/lon fields</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> <span class="hljs-keyword">var</span> lon = doc.get(<span class="hljs-keyword">this</span>.state.get(<span class="hljs-string">'lonField'</span>));
|
||
<span class="hljs-keyword">var</span> lat = doc.get(<span class="hljs-keyword">this</span>.state.get(<span class="hljs-string">'latField'</span>));
|
||
lon = <span class="hljs-keyword">this</span>._parseCoordinateString(lon);
|
||
lat = <span class="hljs-keyword">this</span>._parseCoordinateString(lat);
|
||
|
||
<span class="hljs-keyword">if</span> (!<span class="hljs-built_in">isNaN</span>(<span class="hljs-built_in">parseFloat</span>(lon)) && !<span class="hljs-built_in">isNaN</span>(<span class="hljs-built_in">parseFloat</span>(lat))) {
|
||
<span class="hljs-keyword">return</span> {
|
||
type: <span class="hljs-string">'Point'</span>,
|
||
coordinates: [lon,lat]
|
||
};
|
||
}
|
||
}
|
||
<span class="hljs-keyword">return</span> <span class="hljs-literal">null</span>;
|
||
},</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-34">
|
||
<div class="annotation">
|
||
|
||
<div class="pilwrap ">
|
||
<a class="pilcrow" href="#section-34">¶</a>
|
||
</div>
|
||
<p>Private: Check if there is a field with GeoJSON geometries or alternatively,
|
||
two fields with lat/lon values.</p>
|
||
<p>If not found, the user can define them via the UI form.</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> _setupGeometryField: <span class="hljs-function"><span class="hljs-keyword">function</span><span class="hljs-params">()</span></span>{</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-35">
|
||
<div class="annotation">
|
||
|
||
<div class="pilwrap ">
|
||
<a class="pilcrow" href="#section-35">¶</a>
|
||
</div>
|
||
<p>should not overwrite if we have already set this (e.g. explicitly via state)</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> <span class="hljs-keyword">if</span> (!<span class="hljs-keyword">this</span>._geomReady()) {
|
||
<span class="hljs-keyword">this</span>.state.set({
|
||
geomField: <span class="hljs-keyword">this</span>._checkField(<span class="hljs-keyword">this</span>.geometryFieldNames),
|
||
latField: <span class="hljs-keyword">this</span>._checkField(<span class="hljs-keyword">this</span>.latitudeFieldNames),
|
||
lonField: <span class="hljs-keyword">this</span>._checkField(<span class="hljs-keyword">this</span>.longitudeFieldNames)
|
||
});
|
||
<span class="hljs-keyword">this</span>.menu.state.set(<span class="hljs-keyword">this</span>.state.toJSON());
|
||
}
|
||
},</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-36">
|
||
<div class="annotation">
|
||
|
||
<div class="pilwrap ">
|
||
<a class="pilcrow" href="#section-36">¶</a>
|
||
</div>
|
||
<p>Private: Check if a field in the current model exists in the provided
|
||
list of names.</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> _checkField: <span class="hljs-function"><span class="hljs-keyword">function</span><span class="hljs-params">(fieldNames)</span></span>{
|
||
<span class="hljs-keyword">var</span> field;
|
||
<span class="hljs-keyword">var</span> modelFieldNames = <span class="hljs-keyword">this</span>.model.fields.pluck(<span class="hljs-string">'id'</span>);
|
||
<span class="hljs-keyword">for</span> (<span class="hljs-keyword">var</span> i = <span class="hljs-number">0</span>; i < fieldNames.length; i++){
|
||
<span class="hljs-keyword">for</span> (<span class="hljs-keyword">var</span> j = <span class="hljs-number">0</span>; j < modelFieldNames.length; j++){
|
||
<span class="hljs-keyword">if</span> (modelFieldNames[j].toLowerCase() == fieldNames[i].toLowerCase())
|
||
<span class="hljs-keyword">return</span> modelFieldNames[j];
|
||
}
|
||
}
|
||
<span class="hljs-keyword">return</span> <span class="hljs-literal">null</span>;
|
||
},</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-37">
|
||
<div class="annotation">
|
||
|
||
<div class="pilwrap ">
|
||
<a class="pilcrow" href="#section-37">¶</a>
|
||
</div>
|
||
<p>Private: Zoom to map to current features extent if any, or to the full
|
||
extent if none.</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> _zoomToFeatures: <span class="hljs-function"><span class="hljs-keyword">function</span><span class="hljs-params">()</span></span>{
|
||
<span class="hljs-keyword">var</span> bounds = <span class="hljs-keyword">this</span>.features.getBounds();
|
||
<span class="hljs-keyword">if</span> (bounds && bounds.getNorthEast() && bounds.getSouthWest()){
|
||
<span class="hljs-keyword">this</span>.map.fitBounds(bounds);
|
||
} <span class="hljs-keyword">else</span> {
|
||
<span class="hljs-keyword">this</span>.map.setView([<span class="hljs-number">0</span>, <span class="hljs-number">0</span>], <span class="hljs-number">2</span>);
|
||
}
|
||
},</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-38">
|
||
<div class="annotation">
|
||
|
||
<div class="pilwrap ">
|
||
<a class="pilcrow" href="#section-38">¶</a>
|
||
</div>
|
||
<p>Private: Sets up the Leaflet map control and the features layer.</p>
|
||
<p>The map uses a base layer from <a href="http://www.mapquest.com">MapQuest</a> based
|
||
on <a href="http://openstreetmap.org">OpenStreetMap</a>.</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> _setupMap: <span class="hljs-function"><span class="hljs-keyword">function</span><span class="hljs-params">()</span></span>{
|
||
<span class="hljs-keyword">var</span> self = <span class="hljs-keyword">this</span>;
|
||
<span class="hljs-keyword">this</span>.map = <span class="hljs-keyword">new</span> L.Map(<span class="hljs-keyword">this</span>.$map.get(<span class="hljs-number">0</span>));
|
||
|
||
<span class="hljs-keyword">var</span> mapUrl = <span class="hljs-string">"http://otile{s}-s.mqcdn.com/tiles/1.0.0/osm/{z}/{x}/{y}.png"</span>;
|
||
<span class="hljs-keyword">var</span> osmAttribution = <span class="hljs-string">'Map data &copy; 2011 OpenStreetMap contributors, Tiles Courtesy of <a href="http://www.mapquest.com/" target="_blank">MapQuest</a> <img src="http://developer.mapquest.com/content/osm/mq_logo.png">'</span>;
|
||
<span class="hljs-keyword">var</span> bg = <span class="hljs-keyword">new</span> L.TileLayer(mapUrl, {maxZoom: <span class="hljs-number">18</span>, attribution: osmAttribution ,subdomains: <span class="hljs-string">'1234'</span>});
|
||
<span class="hljs-keyword">this</span>.map.addLayer(bg);
|
||
|
||
<span class="hljs-keyword">this</span>.markers = <span class="hljs-keyword">new</span> L.MarkerClusterGroup(<span class="hljs-keyword">this</span>._clusterOptions);</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-39">
|
||
<div class="annotation">
|
||
|
||
<div class="pilwrap ">
|
||
<a class="pilcrow" href="#section-39">¶</a>
|
||
</div>
|
||
<p>rebind this (as needed in e.g. default case above)</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> <span class="hljs-keyword">this</span>.geoJsonLayerOptions.pointToLayer = _.bind(
|
||
<span class="hljs-keyword">this</span>.geoJsonLayerOptions.pointToLayer,
|
||
<span class="hljs-keyword">this</span>);
|
||
<span class="hljs-keyword">this</span>.features = <span class="hljs-keyword">new</span> L.GeoJSON(<span class="hljs-literal">null</span>, <span class="hljs-keyword">this</span>.geoJsonLayerOptions);
|
||
|
||
<span class="hljs-keyword">this</span>.map.setView([<span class="hljs-number">0</span>, <span class="hljs-number">0</span>], <span class="hljs-number">2</span>);
|
||
|
||
<span class="hljs-keyword">this</span>.mapReady = <span class="hljs-literal">true</span>;
|
||
},</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-40">
|
||
<div class="annotation">
|
||
|
||
<div class="pilwrap ">
|
||
<a class="pilcrow" href="#section-40">¶</a>
|
||
</div>
|
||
<p>Private: Helper function to select an option from a select list</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> _selectOption: <span class="hljs-function"><span class="hljs-keyword">function</span><span class="hljs-params">(id,value)</span></span>{
|
||
<span class="hljs-keyword">var</span> options = $(<span class="hljs-string">'.'</span> + id + <span class="hljs-string">' > select > option'</span>);
|
||
<span class="hljs-keyword">if</span> (options){
|
||
options.each(<span class="hljs-function"><span class="hljs-keyword">function</span><span class="hljs-params">(opt)</span></span>{
|
||
<span class="hljs-keyword">if</span> (<span class="hljs-keyword">this</span>.value == value) {
|
||
$(<span class="hljs-keyword">this</span>).attr(<span class="hljs-string">'selected'</span>,<span class="hljs-string">'selected'</span>);
|
||
<span class="hljs-keyword">return</span> <span class="hljs-literal">false</span>;
|
||
}
|
||
});
|
||
}
|
||
}
|
||
});
|
||
|
||
my.MapMenu = Backbone.View.extend({
|
||
className: <span class="hljs-string">'editor'</span>,
|
||
|
||
template: <span class="hljs-string">' \
|
||
<form class="form-stacked"> \
|
||
<div class="clearfix"> \
|
||
<div class="editor-field-type"> \
|
||
<label class="radio"> \
|
||
<input type="radio" id="editor-field-type-latlon" name="editor-field-type" value="latlon" checked="checked"/> \
|
||
Latitude / Longitude fields</label> \
|
||
<label class="radio"> \
|
||
<input type="radio" id="editor-field-type-geom" name="editor-field-type" value="geom" /> \
|
||
GeoJSON field</label> \
|
||
</div> \
|
||
<div class="editor-field-type-latlon"> \
|
||
<label>Latitude field</label> \
|
||
<div class="input editor-lat-field"> \
|
||
<select class="form-control"> \
|
||
<option value=""></option> \
|
||
{{#fields}} \
|
||
<option value="{{id}}">{{label}}</option> \
|
||
{{/fields}} \
|
||
</select> \
|
||
</div> \
|
||
<label>Longitude field</label> \
|
||
<div class="input editor-lon-field"> \
|
||
<select class="form-control"> \
|
||
<option value=""></option> \
|
||
{{#fields}} \
|
||
<option value="{{id}}">{{label}}</option> \
|
||
{{/fields}} \
|
||
</select> \
|
||
</div> \
|
||
</div> \
|
||
<div class="editor-field-type-geom" style="display:none"> \
|
||
<label>Geometry field (GeoJSON)</label> \
|
||
<div class="input editor-geom-field"> \
|
||
<select class="form-control"> \
|
||
<option value=""></option> \
|
||
{{#fields}} \
|
||
<option value="{{id}}">{{label}}</option> \
|
||
{{/fields}} \
|
||
</select> \
|
||
</div> \
|
||
</div> \
|
||
</div> \
|
||
<div class="editor-buttons"> \
|
||
<button class="btn btn-default editor-update-map">Update</button> \
|
||
</div> \
|
||
<div class="editor-options" > \
|
||
<label class="checkbox"> \
|
||
<input type="checkbox" id="editor-auto-zoom" value="autozoom" checked="checked" /> \
|
||
Auto zoom to features</label> \
|
||
<label class="checkbox"> \
|
||
<input type="checkbox" id="editor-cluster" value="cluster"/> \
|
||
Cluster markers</label> \
|
||
</div> \
|
||
<input type="hidden" class="editor-id" value="map-1" /> \
|
||
</form> \
|
||
'</span>,</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-41">
|
||
<div class="annotation">
|
||
|
||
<div class="pilwrap ">
|
||
<a class="pilcrow" href="#section-41">¶</a>
|
||
</div>
|
||
<p>Define here events for UI elements</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> events: {
|
||
<span class="hljs-string">'click .editor-update-map'</span>: <span class="hljs-string">'onEditorSubmit'</span>,
|
||
<span class="hljs-string">'change .editor-field-type'</span>: <span class="hljs-string">'onFieldTypeChange'</span>,
|
||
<span class="hljs-string">'click #editor-auto-zoom'</span>: <span class="hljs-string">'onAutoZoomChange'</span>,
|
||
<span class="hljs-string">'click #editor-cluster'</span>: <span class="hljs-string">'onClusteringChange'</span>
|
||
},
|
||
|
||
initialize: <span class="hljs-function"><span class="hljs-keyword">function</span><span class="hljs-params">(options)</span> </span>{
|
||
<span class="hljs-keyword">var</span> self = <span class="hljs-keyword">this</span>;
|
||
_.bindAll(<span class="hljs-keyword">this</span>, <span class="hljs-string">'render'</span>);
|
||
<span class="hljs-keyword">this</span>.listenTo(<span class="hljs-keyword">this</span>.model.fields, <span class="hljs-string">'change'</span>, <span class="hljs-keyword">this</span>.render);
|
||
<span class="hljs-keyword">this</span>.state = <span class="hljs-keyword">new</span> recline.Model.ObjectState(options.state);
|
||
<span class="hljs-keyword">this</span>.listenTo(<span class="hljs-keyword">this</span>.state, <span class="hljs-string">'change'</span>, <span class="hljs-keyword">this</span>.render);
|
||
<span class="hljs-keyword">this</span>.render();
|
||
},</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-42">
|
||
<div class="annotation">
|
||
|
||
<div class="pilwrap ">
|
||
<a class="pilcrow" href="#section-42">¶</a>
|
||
</div>
|
||
<h3 id="public-adds-the-necessary-elements-to-the-page-">Public: Adds the necessary elements to the page.</h3>
|
||
<p>Also sets up the editor fields and the map if necessary.</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> render: <span class="hljs-function"><span class="hljs-keyword">function</span><span class="hljs-params">()</span> </span>{
|
||
<span class="hljs-keyword">var</span> self = <span class="hljs-keyword">this</span>;
|
||
<span class="hljs-keyword">var</span> htmls = Mustache.render(<span class="hljs-keyword">this</span>.template, <span class="hljs-keyword">this</span>.model.toTemplateJSON());
|
||
<span class="hljs-keyword">this</span>.$el.html(htmls);
|
||
|
||
<span class="hljs-keyword">if</span> (<span class="hljs-keyword">this</span>._geomReady() && <span class="hljs-keyword">this</span>.model.fields.length){
|
||
<span class="hljs-keyword">if</span> (<span class="hljs-keyword">this</span>.state.get(<span class="hljs-string">'geomField'</span>)){
|
||
<span class="hljs-keyword">this</span>._selectOption(<span class="hljs-string">'editor-geom-field'</span>,<span class="hljs-keyword">this</span>.state.get(<span class="hljs-string">'geomField'</span>));
|
||
<span class="hljs-keyword">this</span>.$el.find(<span class="hljs-string">'#editor-field-type-geom'</span>).attr(<span class="hljs-string">'checked'</span>,<span class="hljs-string">'checked'</span>).change();
|
||
} <span class="hljs-keyword">else</span>{
|
||
<span class="hljs-keyword">this</span>._selectOption(<span class="hljs-string">'editor-lon-field'</span>,<span class="hljs-keyword">this</span>.state.get(<span class="hljs-string">'lonField'</span>));
|
||
<span class="hljs-keyword">this</span>._selectOption(<span class="hljs-string">'editor-lat-field'</span>,<span class="hljs-keyword">this</span>.state.get(<span class="hljs-string">'latField'</span>));
|
||
<span class="hljs-keyword">this</span>.$el.find(<span class="hljs-string">'#editor-field-type-latlon'</span>).attr(<span class="hljs-string">'checked'</span>,<span class="hljs-string">'checked'</span>).change();
|
||
}
|
||
}
|
||
<span class="hljs-keyword">if</span> (<span class="hljs-keyword">this</span>.state.get(<span class="hljs-string">'autoZoom'</span>)) {
|
||
<span class="hljs-keyword">this</span>.$el.find(<span class="hljs-string">'#editor-auto-zoom'</span>).attr(<span class="hljs-string">'checked'</span>, <span class="hljs-string">'checked'</span>);
|
||
} <span class="hljs-keyword">else</span> {
|
||
<span class="hljs-keyword">this</span>.$el.find(<span class="hljs-string">'#editor-auto-zoom'</span>).removeAttr(<span class="hljs-string">'checked'</span>);
|
||
}
|
||
<span class="hljs-keyword">if</span> (<span class="hljs-keyword">this</span>.state.get(<span class="hljs-string">'cluster'</span>)) {
|
||
<span class="hljs-keyword">this</span>.$el.find(<span class="hljs-string">'#editor-cluster'</span>).attr(<span class="hljs-string">'checked'</span>, <span class="hljs-string">'checked'</span>);
|
||
} <span class="hljs-keyword">else</span> {
|
||
<span class="hljs-keyword">this</span>.$el.find(<span class="hljs-string">'#editor-cluster'</span>).removeAttr(<span class="hljs-string">'checked'</span>);
|
||
}
|
||
<span class="hljs-keyword">return</span> <span class="hljs-keyword">this</span>;
|
||
},
|
||
|
||
_geomReady: <span class="hljs-function"><span class="hljs-keyword">function</span><span class="hljs-params">()</span> </span>{
|
||
<span class="hljs-keyword">return</span> <span class="hljs-built_in">Boolean</span>(<span class="hljs-keyword">this</span>.state.get(<span class="hljs-string">'geomField'</span>) || (<span class="hljs-keyword">this</span>.state.get(<span class="hljs-string">'latField'</span>) && <span class="hljs-keyword">this</span>.state.get(<span class="hljs-string">'lonField'</span>)));
|
||
},</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-43">
|
||
<div class="annotation">
|
||
|
||
<div class="pilwrap ">
|
||
<a class="pilcrow" href="#section-43">¶</a>
|
||
</div>
|
||
<h2 id="ui-event-handlers">UI Event handlers</h2>
|
||
|
||
</div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-44">
|
||
<div class="annotation">
|
||
|
||
<div class="pilwrap ">
|
||
<a class="pilcrow" href="#section-44">¶</a>
|
||
</div>
|
||
<p>Public: Update map with user options</p>
|
||
<p>Right now the only configurable option is what field(s) contains the
|
||
location information.</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> onEditorSubmit: <span class="hljs-function"><span class="hljs-keyword">function</span><span class="hljs-params">(e)</span></span>{
|
||
e.preventDefault();
|
||
<span class="hljs-keyword">if</span> (<span class="hljs-keyword">this</span>.$el.find(<span class="hljs-string">'#editor-field-type-geom'</span>).attr(<span class="hljs-string">'checked'</span>)){
|
||
<span class="hljs-keyword">this</span>.state.set({
|
||
geomField: <span class="hljs-keyword">this</span>.$el.find(<span class="hljs-string">'.editor-geom-field > select > option:selected'</span>).val(),
|
||
lonField: <span class="hljs-literal">null</span>,
|
||
latField: <span class="hljs-literal">null</span>
|
||
});
|
||
} <span class="hljs-keyword">else</span> {
|
||
<span class="hljs-keyword">this</span>.state.set({
|
||
geomField: <span class="hljs-literal">null</span>,
|
||
lonField: <span class="hljs-keyword">this</span>.$el.find(<span class="hljs-string">'.editor-lon-field > select > option:selected'</span>).val(),
|
||
latField: <span class="hljs-keyword">this</span>.$el.find(<span class="hljs-string">'.editor-lat-field > select > option:selected'</span>).val()
|
||
});
|
||
}
|
||
<span class="hljs-keyword">return</span> <span class="hljs-literal">false</span>;
|
||
},</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-45">
|
||
<div class="annotation">
|
||
|
||
<div class="pilwrap ">
|
||
<a class="pilcrow" href="#section-45">¶</a>
|
||
</div>
|
||
<p>Public: Shows the relevant select lists depending on the location field
|
||
type selected.</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> onFieldTypeChange: <span class="hljs-function"><span class="hljs-keyword">function</span><span class="hljs-params">(e)</span></span>{
|
||
<span class="hljs-keyword">if</span> (e.target.value == <span class="hljs-string">'geom'</span>){
|
||
<span class="hljs-keyword">this</span>.$el.find(<span class="hljs-string">'.editor-field-type-geom'</span>).show();
|
||
<span class="hljs-keyword">this</span>.$el.find(<span class="hljs-string">'.editor-field-type-latlon'</span>).hide();
|
||
} <span class="hljs-keyword">else</span> {
|
||
<span class="hljs-keyword">this</span>.$el.find(<span class="hljs-string">'.editor-field-type-geom'</span>).hide();
|
||
<span class="hljs-keyword">this</span>.$el.find(<span class="hljs-string">'.editor-field-type-latlon'</span>).show();
|
||
}
|
||
},
|
||
|
||
onAutoZoomChange: <span class="hljs-function"><span class="hljs-keyword">function</span><span class="hljs-params">(e)</span></span>{
|
||
<span class="hljs-keyword">this</span>.state.set({autoZoom: !<span class="hljs-keyword">this</span>.state.get(<span class="hljs-string">'autoZoom'</span>)});
|
||
},
|
||
|
||
onClusteringChange: <span class="hljs-function"><span class="hljs-keyword">function</span><span class="hljs-params">(e)</span></span>{
|
||
<span class="hljs-keyword">this</span>.state.set({cluster: !<span class="hljs-keyword">this</span>.state.get(<span class="hljs-string">'cluster'</span>)});
|
||
},</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-46">
|
||
<div class="annotation">
|
||
|
||
<div class="pilwrap ">
|
||
<a class="pilcrow" href="#section-46">¶</a>
|
||
</div>
|
||
<p>Private: Helper function to select an option from a select list</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> _selectOption: <span class="hljs-function"><span class="hljs-keyword">function</span><span class="hljs-params">(id,value)</span></span>{
|
||
<span class="hljs-keyword">var</span> options = <span class="hljs-keyword">this</span>.$el.find(<span class="hljs-string">'.'</span> + id + <span class="hljs-string">' > select > option'</span>);
|
||
<span class="hljs-keyword">if</span> (options){
|
||
options.each(<span class="hljs-function"><span class="hljs-keyword">function</span><span class="hljs-params">(opt)</span></span>{
|
||
<span class="hljs-keyword">if</span> (<span class="hljs-keyword">this</span>.value == value) {
|
||
$(<span class="hljs-keyword">this</span>).attr(<span class="hljs-string">'selected'</span>,<span class="hljs-string">'selected'</span>);
|
||
<span class="hljs-keyword">return</span> <span class="hljs-literal">false</span>;
|
||
}
|
||
});
|
||
}
|
||
}
|
||
});
|
||
|
||
})(jQuery, recline.View);</pre></div></div>
|
||
|
||
</li>
|
||
|
||
</ul>
|
||
</div>
|
||
</body>
|
||
</html>
|