upgrade
This commit is contained in:
@@ -0,0 +1,56 @@
|
||||
CKEditor Leaflet Map Plugin
|
||||
|
||||
|
||||
I. CREATING NEW MAP
|
||||
|
||||
1.) Click the Leaflet Map icon in the CKEditor Toolbar. The Dialog window will now pop-up.
|
||||
|
||||
Then, it is EITHER of the 2 steps:
|
||||
2) Input the Place name (for example: Manila, Philippines).
|
||||
|
||||
3.) Input the Latitude and Longitude values of a Place in their corresponding text fields.
|
||||
(for example: Latitude = 14.123456 and Longitude = 121.654321)
|
||||
|
||||
Then click the OK button. After that, a map will be created, centered on that specified coordinates, with the following default values:
|
||||
Width: 400px
|
||||
Height: 400px
|
||||
Zoom Level: 10
|
||||
Map Tile: MapQuestOpen.OSM
|
||||
Overview Map (MiniMap): Enabled
|
||||
Alignment: Left
|
||||
|
||||
Note that if you do BOTH #2 and #3 (which is I think will rarely happen), the value in #2 will be ignored and the values/coordinates in #3 will be used.
|
||||
|
||||
|
||||
II. EDITING EXISTING MAP
|
||||
|
||||
It is either of the 2 steps:
|
||||
|
||||
1.) If you hover the mouse on the map, you will see the map's handle bar (cross hair) in the UPPER LEFT corner of the map,
|
||||
you could then double-click that to view or edit the map properties.
|
||||
|
||||
2.) With your mouse, select the map to be edited (to set the focus away from other CKEditor objects). Then click the Leaflet Map icon in the CKEditor toolbar.
|
||||
|
||||
The Dialog will pop-up and will be set to the properties of the currently selected map.
|
||||
Note that the #1 is the preferred way.
|
||||
|
||||
To set the current map in a NEW location, either specify a new Place name value in the Search field, or specify a new Lat/Lon values in the corresponding text fields. Note that if you change BOTH the values in the Search field and the Lat/Lon fields (which is I think will rarely happen), the values in the Lat/Lon fields will be used.
|
||||
|
||||
You might be wondering why the #1 step has to be done that way.
|
||||
The main reason is that CKEditor Leaflet Maps uses the Widget API (introduced in CKEditor 4.3).
|
||||
The Widget API introduces innovative features and more plugin flexibility.
|
||||
|
||||
For one, the map could have a Map Mode and Widget Mode.
|
||||
Map mode uses the mouse wheel or double-click for zooming the map,
|
||||
Left-Click+Hold+Drag for panning the map,
|
||||
and the possibility to use the map's '+/-' zoom UI buttons.
|
||||
|
||||
We could have opted to bind the double-click for showing the map's option
|
||||
at the expense of lesser map interaction. However, since I believe that map interaction
|
||||
is relatively more important compared to widget's interaction, we need to compromise a bit.
|
||||
That's why in order to edit the map's options, we have to do a mouse hover onto the map
|
||||
and double-click the default widget's handle bars in the map's upper left corner
|
||||
so that the default map's behavior and mouse and key bindings could still be preserved.
|
||||
|
||||
Later, we might include the option to edit the map widget's option
|
||||
using the Right-Click or Ctrl+Left-Click event bindings.
|
||||
@@ -0,0 +1,203 @@
|
||||
I. OVERVIEW
|
||||
|
||||
This Leaflet Maps plugin requires CKEditor 4.3 or later versions, and it leverages the power and flexibility
|
||||
of Widget API. Hence, the 'widget' plugin is also a hard dependency (which also depends on Line Utilities
|
||||
and Clipboard plugins). The Clipboard plugin is already loaded by default in all presets/pre-built packages of CKEditor
|
||||
(Basic, Standard, and Full). Hence, we only need to download the Widget plugin (http://ckeditor.com/addon/widget),
|
||||
the Line Utilities plugin (http://ckeditor.com/addon/lineutils), and this Leaflet Maps plugin (http://ckeditor.com/addon/leaflet).
|
||||
|
||||
For Linux users, after downloading, make sure that the zipped folders or the target CKEditor folders
|
||||
have right read/write/execute permissions, otherwise you might encounter loading issues
|
||||
like the "File x could not be found" notice. You might need to run "sudo chmod 777 -R leaflet",
|
||||
"sudo chmod 777 -R lineutils", and "sudo chmod 777 -R widget" before or after copying them
|
||||
in the appropriate CKEditor folders.
|
||||
|
||||
|
||||
II. STANDARD INSTALLATION (Usual Setup)
|
||||
|
||||
1) After unzipping the folder, paste the three folders ("lineutils", "leaflet", and "widget")
|
||||
to "ckeditor/plugins" folder. After that, you should have the following folder structures:
|
||||
"ckeditor/plugins/leaflet"
|
||||
"ckeditor/plugins/lineutils"
|
||||
"ckeditor/plugins/widget"
|
||||
|
||||
2) Edit the "ckeditor/config.js" file, and add the following:
|
||||
if there's no existing line yet:
|
||||
config.extraPlugins = "lineutils,widget,leaflet";
|
||||
|
||||
otherwise, append it to the existing list, no extra spaces are allowed:
|
||||
config.extraPlugins = "existing_plugin,another_existing_plugin,lineutils,widget,leaflet";
|
||||
|
||||
3.) Just to make sure, clear the web browser's cache after modifying your configuration.
|
||||
Clearing the browser's cache is also very important
|
||||
since the CKEditor's JS and CSS assets/components are cached also in the browser.
|
||||
|
||||
|
||||
III. DRUPAL INSTALLATION
|
||||
|
||||
In Drupal, the typical way to embed the CKEditor WSYIWYG is
|
||||
through the CKEditor module (https://drupal.org/project/ckeditor),
|
||||
and then loading the corresponding CKEditor JS library (http://ckeditor.com/).
|
||||
|
||||
Drupal's CKEditor module (tested on version ) is typically installed to have this internal path:
|
||||
sites/all/modules/ckeditor or sites/all/modules/contrib/ckeditor.
|
||||
|
||||
Note that this guide is tested on CKEditor "7.x-1.13", latest version is "7.x-1.14".
|
||||
I'll test this guide also in the latest version later.
|
||||
|
||||
Moreover, the CKeditor JS Library is typically installed to have this internal path:
|
||||
"sites/all/modules/ckeditor/ckeditor/ckeditor.js" or
|
||||
"sites/all/modules/contrib/ckeditor/ckeditor/ckeditor.js" or
|
||||
"sites/all/libraries/ckeditor/ckeditor.js."
|
||||
|
||||
However, installing additional plugins in CKEditor in Drupal is not that straightforward
|
||||
as we could see from the issue queues:
|
||||
https://drupal.org/node/2215409#comment-8568207
|
||||
https://drupal.org/node/1930130#comment-7297628
|
||||
https://drupal.org/node/1324554
|
||||
https://drupal.org/node/2215497
|
||||
|
||||
Nevertheless, after experimenting with the various ways to enable the additional plugins
|
||||
(Line Utilities, Widget, and Leaflet), this is the simplest solution
|
||||
(the idea is to copy the plugin folders, enable them, and make them visible in the toolbar):
|
||||
|
||||
|
||||
A. DRUPAL INSTALLATION OPTION 1
|
||||
|
||||
1.) Download and unzip the plugins here (depending on your setup):
|
||||
"sites/all/modules/ckeditor/plugins" or
|
||||
"sites/all/modules/contrib/ckeditor/plugins".
|
||||
|
||||
After that, you should have the following folder structures:
|
||||
"ckeditor/plugins/leaflet"
|
||||
"ckeditor/plugins/lineutils"
|
||||
"ckeditor/plugins/widget"
|
||||
|
||||
2.) We should now activate the new plugins and add them to the toolbar.
|
||||
This is done by configuring the CKEditor Profile Settings,
|
||||
in which by default is located in:
|
||||
"admin/config/content/ckeditor/edit/Advanced"
|
||||
|
||||
A. Activate the Plugins
|
||||
In EDITOR APPEARANCE >>> Plugins section:
|
||||
Enable the corresponding checkboxes for the Leaflet Maps, Line Utilities,
|
||||
and Widget plugins. These are the texts displayed adjacent to their checkboxes:
|
||||
"Plugin file: leaflet"
|
||||
"Plugin file: lineutils"
|
||||
"Plugin file: widget"
|
||||
|
||||
B. Add them to the Toolbar
|
||||
We should then make the activated plugins visible in the toolbar,
|
||||
skipping this step will make the Leaflet Maps plugin inaccessible in the toolbar.
|
||||
|
||||
In EDITOR APPEARANCE >>> Toolbar section:
|
||||
Drag the Leaflet Maps icon (black-colored) from the 'All Buttons' section
|
||||
to the 'Used Buttons' section.
|
||||
|
||||
We need to configure the Leaflet Maps icon only since the Line Utilities and Widget plugins
|
||||
have no toolbar icons and they will just load in the background.
|
||||
|
||||
3.) Then, click the Save button. Clear the Drupal's overall cache AND
|
||||
clear the browser's cache. Clearing the browser's cache is also
|
||||
very important since the CKEditor's JS and CSS assets/components
|
||||
are cached also in the browser.
|
||||
|
||||
As indicated above, using the "sites/all/modules/ckeditor/plugins" or
|
||||
"sites/all/modules/contrib/ckeditor/plugins"
|
||||
will work with no additional custom hooks programming since by default
|
||||
CKEditor utilize that folder in the CKEditor Global Profile Settings:
|
||||
"admin/config/content/ckeditor/editg".
|
||||
|
||||
If you go that Global Profile Settings page, this will be indicated
|
||||
(unless you override the default configuration):
|
||||
Path to the CKEditor plugins directory: "%m/plugins"
|
||||
|
||||
In which "%m" refers to the base URL path where the CKEditor module is stored,
|
||||
and defaults to "sites/all/modules/ckeditor" or "sites/all/modules/contrib/ckeditor".
|
||||
|
||||
|
||||
B. DRUPAL INSTALLATION OPTION 2
|
||||
|
||||
With the advent of Libraries API (https://drupal.org/project/libraries),
|
||||
Drupal offers more flexibility in the handling of external/third-party libraries,
|
||||
which means a clean mechanism that provides a separation of control between
|
||||
the CKEditor module and CKEditor library, and implies that we could
|
||||
safely upgrade the library and module independent to each other.
|
||||
Having a Libraries folder (sites/all/libraries) is also a very common setup in Drupal.
|
||||
|
||||
This setup assumes that you've already installed and enabled the Libraries API module
|
||||
and configured the CKEditor library (sites/all/libraries/ckeditor).
|
||||
Make sure also that the "Path to CKEditor" settings indicated in
|
||||
the CKEditor's Global Profile (admin/config/content/ckeditor/editg) is
|
||||
indicated as "%l/ckeditor", in which "%l" refers to the "sites/all/libraries".
|
||||
|
||||
1.) Download and unzip the plugins here:
|
||||
"sites/all/libraries/ckeditor/plugins"
|
||||
|
||||
After that, you should have the following folder structures:
|
||||
"ckeditor/plugins/leaflet"
|
||||
"ckeditor/plugins/lineutils"
|
||||
"ckeditor/plugins/widget"
|
||||
|
||||
2.) We should now activate the new plugins and add them to the toolbar.
|
||||
This is done by implementing first the hook_ckeditor_plugin() in a custom module:
|
||||
|
||||
function MYMODULE_ckeditor_plugin() {
|
||||
return array(
|
||||
'leaflet' => array(
|
||||
'name' => 'Leaflet Maps',
|
||||
'desc' => t('Plugin for inserting Leaflet Maps.'),
|
||||
'path' => libraries_get_path('ckeditor') . '/plugins/leaflet/',
|
||||
'buttons' => array(
|
||||
'leaflet' => array(
|
||||
'label' => 'Leaflet Maps',
|
||||
'icon' => 'icons/leaflet.png',
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
For convenience, I've created a Drupal utility module specifically for this purpose,
|
||||
check-out the module and instructions here:
|
||||
https://github.com/ranelpadon/drupal-leaflet-maps/tree/master
|
||||
|
||||
Fortunately, we need only to register the Leaflet Maps plugin,
|
||||
the Line Utilities and Widget plugins are automatically registered.
|
||||
The Leaflet Maps Drupal module above is enough for our purpose.
|
||||
|
||||
Now, we configure the CKEditor Profile Settings,
|
||||
in which by default is located in:
|
||||
"admin/config/content/ckeditor/edit/Advanced"
|
||||
|
||||
A. Activate the Plugin
|
||||
In EDITOR APPEARANCE >>> Plugins section:
|
||||
Enable the corresponding checkbox for the Leaflet Maps plugin.
|
||||
This is the description displayed adjacent to its checkbox:
|
||||
"Plugin for inserting Leaflet Maps."
|
||||
|
||||
B. Add them to the Toolbar
|
||||
We should then make the activated plugin visible in the toolbar,
|
||||
skipping this step will make the Leaflet Maps plugin inaccessible in the toolbar.
|
||||
|
||||
In EDITOR APPEARANCE >>> Toolbar section:
|
||||
Drag the Leaflet Maps icon (black-colored) from the 'All Buttons' section
|
||||
to the 'Used Buttons' section.
|
||||
|
||||
We need to configure the Leaflet Maps icon only since
|
||||
the Line Utilities and Widget plugins have no toolbar icons and
|
||||
they will just load in the background.
|
||||
|
||||
3.) Then, click the Save button. Clear the Drupal's overall cache AND
|
||||
clear the browser's cache. Clearing the browser's cache is also
|
||||
very important since the CKEditor's JS and CSS assets/components
|
||||
are cached also in the browser.
|
||||
|
||||
Note that if you configure the Leaflet Maps, Line Utilities, and Widget plugins
|
||||
using the handy CKEditor auto-builder (http://ckeditor.com/builder) and
|
||||
bundled it with the core "ckeditor.js" file, it will not work in Drupal,
|
||||
since as far as I know, the Drupal's CKEditor module
|
||||
(or specifically the hook_ckeditor_plugin()) has no support for it yet.
|
||||
|
||||
But, outside of Drupal, the Leaflet Maps will work even when
|
||||
pre-configured/auto-bundled using the CKEditor builder.
|
||||
72
main/inc/lib/javascript/ckeditor/plugins/leaflet/README.md
Normal file
72
main/inc/lib/javascript/ckeditor/plugins/leaflet/README.md
Normal file
@@ -0,0 +1,72 @@
|
||||
ckeditor-leaflet
|
||||
================
|
||||
<strong>OVERVIEW</strong>:<br>
|
||||
This CKEditor <a href="http://ckeditor.com/addon/leaflet">Leaflet Maps</a> plugin has three workhorse files:
|
||||
<ul>
|
||||
<li><a href="https://github.com/ranelpadon/ckeditor-leaflet/blob/master/plugin.js">Plugin Core</a>: Defines the plugin and attaches the plugin to the CKEditor toolbar.</li>
|
||||
<li><a href="https://github.com/ranelpadon/ckeditor-leaflet/blob/master/dialogs/leaflet.js">Dialog Script</a>: Displays the map options when creating and editing existing maps.</li>
|
||||
<li><a href="https://github.com/ranelpadon/ckeditor-leaflet/blob/master/scripts/mapParser.html">Map Renderer</a>: Parses the map options via URL and renders the map accordingly.</li>
|
||||
</ul>
|
||||
|
||||
This plugin utilizes the following technologies/libraries: <br>
|
||||
<ul>
|
||||
<li><a href="http://docs.ckeditor.com/#!/api/CKEDITOR.plugins.widget">CKEditor's Widget API</a></li>
|
||||
<li><a href="https://developers.google.com/maps/documentation/javascript/places-autocomplete">Google's Places Library/Type-Ahead Search</a></li>
|
||||
<li><a href="https://developers.google.com/maps/documentation/geocoding/">Google's Geocoding API</a></li>
|
||||
<li><a href="http://leafletjs.com/">Leaflet JS</a></li>
|
||||
<li><a href="https://github.com/leaflet-extras/leaflet-providers">Leaflet - Tile Providers</a></li>
|
||||
<li><a href="https://github.com/Norkart/Leaflet-MiniMap">Leaflet - MiniMap</a></li>
|
||||
</ul>
|
||||
|
||||
<strong>LIVE DEMO PAGE</strong>:
|
||||
<br>Demo page could be found here: http://ranelpadon.github.io/ckeditor-leaflet/index.html
|
||||
|
||||
<strong>INSTALLATION</strong>:
|
||||
<br>Kindly refer to <a href="https://github.com/ranelpadon/ckeditor-leaflet/blob/master/Installation%20Guide.txt">Installation Guide</a>
|
||||
|
||||
<strong>HOW TO USE</strong>:
|
||||
<br>Kindly refer to <a href="https://github.com/ranelpadon/ckeditor-leaflet/blob/master/Creating%20and%20Editing%20Leaflet%20Maps.txt">How to Create and Edit Leaflet Maps</a>
|
||||
|
||||
<strong>ROAD MAP</strong> (Planned stuff to do):<br><ul>
|
||||
<li>Option to show the cursor's map coordinates and scale bar.</li>
|
||||
<li>Marker could be dragged and its dragged position must be saved.</li>
|
||||
<li>State of the panned map's view must be saved.</li>
|
||||
<li>Responsive behavior (for mobile pages).
|
||||
<li>Ability to add map caption/annotation
|
||||
<li>Display the map preview in the Dialog window.</li>
|
||||
<li>Handle multiple markers.</li>
|
||||
<li>Add and delete markers.</li>
|
||||
<li>Has option to add Panoromio (panoramio.com) layer.</li>
|
||||
<li>Add other tile providers.</li>
|
||||
<li>R&D other Leaflet plugins that might be useful.</li>
|
||||
</ul>
|
||||
|
||||
<strong>LICENSE and CREDITS</strong>:<br>
|
||||
|
||||
License: <a href="https://www.gnu.org/licenses/lgpl.html">LGPL v3</a> applies.<br>
|
||||
Copyright 2014 by Engr. Ranel O. Padon<br>
|
||||
ranel.padon@gmail.com<br>
|
||||
|
||||
Plugin's icon is a property of <a href="http://simpleicon.com/">simpleicon</a>.
|
||||
As indicated in their website, use of their icon is allowed as long as it includes proper credit and backlink.
|
||||
|
||||
Thanks to CKEditor, Leaflet, and other great open-source softwares and their unsung developers.<br>
|
||||
|
||||
Special thanks also to the insights, guidance, and collaborative support of our <a href="http://travel.cnn.com">CNN Travel</a> team:<br>
|
||||
Senior Web Development Manager:<br>
|
||||
Brent A. Deverman<br>
|
||||
|
||||
Senior Software Engineer:<br>
|
||||
Adrian Christopher B. Cruz<br>
|
||||
|
||||
Senior QA Analyst:<br>
|
||||
Jonathan A. Jacinto<br>
|
||||
|
||||
=======================================================
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,25 @@
|
||||
.leaflet_div {
|
||||
background: #eee;
|
||||
border: 1px solid #ddd;
|
||||
border-radius: 4pxt;
|
||||
box-shadow: 0 1px 1px #fff inset, 0 -1px 0px #ccc inset;
|
||||
margin-right: 1em;
|
||||
}
|
||||
|
||||
.leaflet_div.align-left {
|
||||
float: left;
|
||||
}
|
||||
|
||||
.leaflet_div.align-right {
|
||||
float: right;
|
||||
}
|
||||
|
||||
.leaflet_div.align-center {
|
||||
display: table;
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
}
|
||||
|
||||
.cke_widget_wrapper:hover>.cke_widget_element {
|
||||
outline: 3px solid yellow !important;
|
||||
}
|
||||
@@ -0,0 +1,400 @@
|
||||
CKEDITOR.dialog.add('leaflet', function(editor) {
|
||||
// Dialog's function callback for the Leaflet Map Widget.
|
||||
return {
|
||||
title: 'Create/Edit Leaflet Map',
|
||||
minWidth: 320,
|
||||
minHeight: 125,
|
||||
|
||||
contents: [{
|
||||
// Create a Location tab.
|
||||
id: 'location_tab',
|
||||
label: 'Location',
|
||||
elements: [
|
||||
{
|
||||
id: 'map_geocode',
|
||||
className: 'geocode',
|
||||
type: 'text',
|
||||
label: 'Auto-Search of Coordinates.',
|
||||
style: 'margin-top: -7px;',
|
||||
|
||||
setup: function(widget) {
|
||||
this.setValue("");
|
||||
},
|
||||
|
||||
onShow: function (widget) {
|
||||
// Get the DOM reference for the Search field.
|
||||
var input = jQuery(".geocode input")[0];
|
||||
|
||||
// Bind the Search field to the Autocomplete widget.
|
||||
var autocomplete = new google.maps.places.Autocomplete(input);
|
||||
|
||||
// Fix for the Google's type-ahead search displaying behind
|
||||
// the widgets dialog window.
|
||||
// Basically, we want to override the z-index of the
|
||||
// Seach Autocomplete list, in which the styling is being set
|
||||
// in real-time by Google.
|
||||
// Make a new DOM element.
|
||||
var stylesheet = jQuery('<style type="text/css" />');
|
||||
|
||||
// Set the inner HTML. Include also the vertical alignment
|
||||
// adjustment for the MiniMap checkbox.
|
||||
stylesheet.html('.pac-container { z-index: 100000 !important;} input.minimap { margin-top: 18px !important; }');
|
||||
|
||||
// Append to the main document's Head section.
|
||||
jQuery('head').append(stylesheet);
|
||||
},
|
||||
},
|
||||
|
||||
{ // Dummy element serving as label/text container only.
|
||||
type: 'html',
|
||||
id: 'map_label',
|
||||
className: 'label',
|
||||
style: 'margin-bottom: -10px;',
|
||||
html: '<p>Manual Input of Coordinates:</p>'
|
||||
},
|
||||
|
||||
{
|
||||
// Create a new horizontal group.
|
||||
type: 'hbox',
|
||||
// Set the relative widths of Latitude, Longitude and Zoom fields.
|
||||
widths: [ '50%', '50%' ],
|
||||
children: [
|
||||
{
|
||||
id: 'map_latitude',
|
||||
className: 'latitude',
|
||||
type: 'text',
|
||||
label: 'Latitude',
|
||||
|
||||
setup: function(widget) {
|
||||
// Set the Lat values if widget has previous value.
|
||||
if (widget.element.data('lat') != "") {
|
||||
this.setValue(widget.element.data('lat'));
|
||||
}
|
||||
},
|
||||
},
|
||||
|
||||
{
|
||||
id: 'map_longitude',
|
||||
className: 'longitude',
|
||||
type: 'text',
|
||||
label: 'Longitude',
|
||||
|
||||
setup: function(widget) {
|
||||
// Set the Lat values if widget has previous value.
|
||||
if (widget.element.data('lon') != "") {
|
||||
this.setValue(widget.element.data('lon'));
|
||||
}
|
||||
},
|
||||
},
|
||||
]
|
||||
},
|
||||
|
||||
{
|
||||
id: 'popup_text',
|
||||
className: 'popup-text',
|
||||
type: 'text',
|
||||
label: 'Pop-up Text (Optional)',
|
||||
style: 'margin-bottom: 8px;',
|
||||
|
||||
setup: function(widget) {
|
||||
// Set the Lat values if widget has previous value.
|
||||
if (widget.element.data('popup-text') != "") {
|
||||
this.setValue(widget.element.data('popup-text'));
|
||||
}
|
||||
|
||||
else {
|
||||
// Set a diffused/default text for better user experience.
|
||||
jQuery(".popup-text input").attr("placeholder", "Enter the marker's text.")
|
||||
}
|
||||
},
|
||||
},
|
||||
]
|
||||
},
|
||||
|
||||
{
|
||||
// Create an Options tab.
|
||||
id: 'options_tab',
|
||||
label: 'Options',
|
||||
elements: [
|
||||
{
|
||||
// Create a new horizontal group.
|
||||
type: 'hbox',
|
||||
style: 'margin-top: -7px;',
|
||||
// Set the relative widths of Latitude, Longitude and Zoom fields.
|
||||
widths: [ '38%', '38%', '24%' ],
|
||||
children: [
|
||||
{
|
||||
id: 'width',
|
||||
className: 'map_width',
|
||||
type: 'text',
|
||||
label: 'Map Width',
|
||||
|
||||
setup: function(widget) {
|
||||
// Set a diffused/default text for better user experience.
|
||||
jQuery(".map_width input").attr("placeholder", "400")
|
||||
|
||||
// Set the map width value if widget has a previous value.
|
||||
if (widget.element.data('width') != "") {
|
||||
this.setValue(widget.element.data('width'));
|
||||
}
|
||||
},
|
||||
},
|
||||
|
||||
{
|
||||
id: 'height',
|
||||
className: 'map_height',
|
||||
type: 'text',
|
||||
label: 'Map Height',
|
||||
|
||||
setup: function(widget) {
|
||||
// Set a diffused/default text for better user experience.
|
||||
jQuery(".map_height input").attr("placeholder", "400")
|
||||
|
||||
// Set the map height value if widget has a previous value.
|
||||
if (widget.element.data('height') != "") {
|
||||
this.setValue(widget.element.data('height'));
|
||||
}
|
||||
},
|
||||
},
|
||||
|
||||
{
|
||||
// Create a select list for Zoom Levels.
|
||||
// 'className' attribute is used for targeting this element in jQuery.
|
||||
id: 'map_zoom',
|
||||
className: 'zoom',
|
||||
type: 'select',
|
||||
label: 'Zoom Level',
|
||||
width: '70px',
|
||||
items: [['1'], ['2'], ['3'], ['4'],['5'], ['6'], ['7'], ['8'], ['9'], ['10'], ['11'], ['12'], ['13'], ['14'], ['15'], ['16'], ['17'], ['18'], ['19'], ['20']],
|
||||
|
||||
// This will execute also every time you edit/double-click the widget.
|
||||
setup: function(widget) {
|
||||
// Set this Zoom Level's select list when
|
||||
// the current location has been initialized and set previously.
|
||||
if (widget.element.data('zoom') != "") {
|
||||
// Get the previously saved zoom value data attribute.
|
||||
// It will be compared to the current value in the map view.
|
||||
var zoomSaved = widget.element.data('zoom');
|
||||
|
||||
// Get the zoom level's snapshot because the current user
|
||||
// might have changed it via mouse events or via the zoom bar.
|
||||
var zoomIframe = widget.element.getChild(0).$.contentDocument.getElementById("map_container").getAttribute("data-zoom");
|
||||
|
||||
if (zoomIframe != zoomSaved) {
|
||||
// Update the saved zoom value in data attribute.
|
||||
zoomSaved = zoomIframe;
|
||||
}
|
||||
|
||||
this.setValue(zoomSaved);
|
||||
}
|
||||
|
||||
// Set the Default Zoom Level value.
|
||||
else {
|
||||
this.setValue("10");
|
||||
}
|
||||
},
|
||||
}
|
||||
]
|
||||
},
|
||||
|
||||
{
|
||||
// Create a new horizontal group.
|
||||
type: 'hbox',
|
||||
// Set the relative widths the tile and overview map fields.
|
||||
widths: [ '50%', '50%' ],
|
||||
children: [
|
||||
{
|
||||
// Create a select list for map tiles.
|
||||
// 'className' attribute is used for targeting this element in jQuery.
|
||||
type: 'select',
|
||||
id: 'map_tile',
|
||||
className: 'tile',
|
||||
label: 'Base Map Tile',
|
||||
items: [['MapQuestOpen.OSM'], ['MapQuestOpen.Aerial'], ['OpenStreetMap.Mapnik'], ['OpenStreetMap.DE'], ['OpenStreetMap.HOT'], ['Esri.DeLorme'], ['Esri.NatGeoWorldMap'], ['Esri.WorldPhysical'], ['Esri.WorldTopoMap'], ['Thunderforest.OpenCycleMap'], ['Thunderforest.Landscape'], ['Stamen.Watercolor']],
|
||||
|
||||
// This will execute also every time you edit/double-click the widget.
|
||||
setup: function(widget) {
|
||||
// Set the Tile data attribute.
|
||||
if (widget.element.data('tile') != "") {
|
||||
this.setValue(widget.element.data('tile'));
|
||||
}
|
||||
|
||||
else {
|
||||
// Set the default value.
|
||||
this.setValue('MapQuestOpen.OSM');
|
||||
}
|
||||
},
|
||||
|
||||
// This will execute every time you click the Dialog's OK button.
|
||||
// It will inject a map iframe in the CKEditor page.
|
||||
commit: function(widget) {
|
||||
// Remove the iframe if it has one.
|
||||
widget.element.setHtml('');
|
||||
|
||||
// Retrieve the value in the Search field.
|
||||
var geocode = jQuery('.geocode input').val();
|
||||
var latitude, longitude;
|
||||
|
||||
if (geocode != "") {
|
||||
// No need to call the encodeURIComponent().
|
||||
var geocodingRequest = "https://maps.googleapis.com/maps/api/geocode/json?address=" + geocode + "&sensor=false";
|
||||
|
||||
// Disable the asynchoronous behavior temporarily so that
|
||||
// waiting for results will happen before proceeding
|
||||
// to the next statements.
|
||||
jQuery.ajaxSetup({
|
||||
async: false
|
||||
});
|
||||
|
||||
// Geocode the retrieved place name.
|
||||
jQuery.getJSON(geocodingRequest, function(data) {
|
||||
if (data["status"] != "ZERO_RESULTS") {
|
||||
// Get the Latitude and Longitude object in the
|
||||
// returned JSON object.
|
||||
latitude = data.results[0].geometry.location.lat;
|
||||
longitude = data.results[0].geometry.location.lng;
|
||||
}
|
||||
|
||||
// Handle queries with no results or have some
|
||||
// malformed parameters.
|
||||
else {
|
||||
alert("The Place could not be Geocoded properly. Kindly choose another one.")
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// Get the Lat/Lon values from the corresponding fields.
|
||||
var latInput = jQuery('.latitude input').val();
|
||||
var lonInput = jQuery('.longitude input').val();
|
||||
|
||||
// Get the data-lat and data-lon values.
|
||||
// It is empty for yet to be created widgets.
|
||||
var latSaved = widget.element.data('lat');
|
||||
var lonSaved = widget.element.data('lon');
|
||||
|
||||
// Used the inputted values if it's not empty or
|
||||
// not equal to the previously saved values.
|
||||
// latSaved and lonSaved are initially empty also
|
||||
// for widgets that are yet to be created.
|
||||
// Or if the user edited an existing map, and did not edit
|
||||
// the lat/lon fields, and the Search field is empty.
|
||||
if ((latInput != "" && lonInput != "") && ((latInput != latSaved && lonInput != lonSaved) || geocode == "")) {
|
||||
latitude = latInput;
|
||||
longitude = lonInput;
|
||||
}
|
||||
|
||||
var width = jQuery(".map_width input").val() || "400";
|
||||
var height = jQuery(".map_height input").val() || "400";
|
||||
var zoom = jQuery('select.zoom').val();
|
||||
var popUpText = jQuery(".popup-text input").val();
|
||||
var tile = jQuery('select.tile').val();
|
||||
var alignment = jQuery('select.alignment').val();
|
||||
|
||||
// Returns 'on' or 'undefined'.
|
||||
var minimap = jQuery('.minimap input:checked').val();
|
||||
|
||||
// Use 'off' if the MiniMap checkbox is unchecked.
|
||||
if (minimap == undefined) {
|
||||
minimap = 'off';
|
||||
}
|
||||
|
||||
// Get a unique timestamp:
|
||||
var milliseconds = new Date().getTime();
|
||||
|
||||
// Set/Update the widget's data attributes.
|
||||
widget.element.setAttribute('id', 'leaflet_div-' + milliseconds);
|
||||
|
||||
widget.element.data('lat', latitude);
|
||||
widget.element.data('lon', longitude);
|
||||
widget.element.data('width', width);
|
||||
widget.element.data('height', height);
|
||||
widget.element.data('zoom', zoom);
|
||||
widget.element.data('popup-text', popUpText);
|
||||
widget.element.data('tile', tile);
|
||||
widget.element.data('minimap', minimap);
|
||||
widget.element.data('alignment', alignment);
|
||||
|
||||
// Remove the previously set alignment class.
|
||||
// Only one alignment class is set per map.
|
||||
widget.element.removeClass('align-left');
|
||||
widget.element.removeClass('align-right');
|
||||
widget.element.removeClass('align-center');
|
||||
|
||||
// Set the alignment for this map.
|
||||
widget.element.addClass('align-' + alignment);
|
||||
|
||||
// Build the full path to the map renderer.
|
||||
mapParserPathFull = mapParserPath + "?lat=" + latitude + "&lon=" + longitude + "&width=" + width + "&height=" + height + "&zoom=" + zoom + "&text=" + popUpText + "&tile=" + tile + "&minimap=" + minimap;
|
||||
|
||||
// Create a new CKEditor DOM's iFrame.
|
||||
var iframe = new CKEDITOR.dom.element('iframe');
|
||||
|
||||
// Setup the iframe characteristics.
|
||||
iframe.setAttributes({
|
||||
'scrolling': 'no',
|
||||
'id': 'leaflet_iframe-' + milliseconds,
|
||||
'class': 'leaflet_iframe',
|
||||
'width': width + 'px',
|
||||
'height': height + 'px',
|
||||
'frameborder': 0,
|
||||
'allowTransparency': true,
|
||||
'src': mapParserPathFull,
|
||||
'data-cke-saved-src': mapParserPathFull
|
||||
});
|
||||
|
||||
// Insert the iframe to the widget's DIV element.
|
||||
widget.element.append(iframe);
|
||||
},
|
||||
},
|
||||
|
||||
{
|
||||
type: 'checkbox',
|
||||
id: 'map_mini',
|
||||
className: 'minimap',
|
||||
label: 'Include MiniMap',
|
||||
|
||||
// This will execute also every time you edit/double-click the widget.
|
||||
setup: function(widget) {
|
||||
// Set the MiniMap check button.
|
||||
if (widget.element.data('minimap') != "" && widget.element.data('minimap') != "on") {
|
||||
this.setValue('');
|
||||
}
|
||||
|
||||
else {
|
||||
// Set the default value.
|
||||
this.setValue('true');
|
||||
}
|
||||
},
|
||||
}
|
||||
]
|
||||
},
|
||||
|
||||
{
|
||||
// Create a select list for Map Alignment.
|
||||
// 'className' attribute is used for targeting this element in jQuery.
|
||||
id: 'map_alignment',
|
||||
className: 'alignment',
|
||||
type: 'select',
|
||||
label: 'Alignment',
|
||||
items: [['Left', 'left'], ['Right', 'right'], ['Center', 'center']],
|
||||
style: 'margin-bottom: 4px;',
|
||||
|
||||
// This will execute also every time you edit/double-click the widget.
|
||||
setup: function(widget) {
|
||||
// Set this map alignment's select list when
|
||||
// the current map has been initialized and set previously.
|
||||
if (widget.element.data('alignment') != "") {
|
||||
// Set the alignment.
|
||||
this.setValue(widget.element.data('alignment'));
|
||||
}
|
||||
|
||||
// Set the Default alignment value.
|
||||
else {
|
||||
this.setValue("left");
|
||||
}
|
||||
},
|
||||
}
|
||||
]
|
||||
}]
|
||||
};
|
||||
});
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 269 B |
170
main/inc/lib/javascript/ckeditor/plugins/leaflet/plugin.js
Normal file
170
main/inc/lib/javascript/ckeditor/plugins/leaflet/plugin.js
Normal file
@@ -0,0 +1,170 @@
|
||||
/**
|
||||
* @fileOverview Leaflet Map Widget.
|
||||
*/
|
||||
(function() {
|
||||
/* Flow of Control for CKEditor and Widget components:
|
||||
Loading the page:
|
||||
CKEditor init()
|
||||
Widget upcast()
|
||||
|
||||
Creating new widgets:
|
||||
Widget init()
|
||||
Widget data()
|
||||
Dialog select element's items()
|
||||
Dialog onShow()
|
||||
Dialog setup()
|
||||
Dialog commit()
|
||||
|
||||
When editing existing widgets:
|
||||
Dialog onShow()
|
||||
Dialog setup()
|
||||
Dialog commit()
|
||||
Widget data()
|
||||
|
||||
When saving page or clicking the CKEditor's Source button:
|
||||
Widget downcast()
|
||||
*/
|
||||
|
||||
// Dummy global method for quick workaround of asynchronous document.write()
|
||||
// issue of Google APIs with respect to CKEditor.
|
||||
// See the Google APIs URL below for the query string usage of this dummy().
|
||||
// Using this hack, the document.write(...) requirement of Google APIs
|
||||
// will be replaced by the more 'gentle' combination of
|
||||
// document.createElement(...) and document.body.appendChild(...).
|
||||
window.dummy = function(){
|
||||
// Do nothing.
|
||||
}
|
||||
|
||||
// Load the needed external libraries. This is asynchronous loading,
|
||||
// that is, they will be loaded in parallel to boost performance.
|
||||
// See also CKEDITOR.scriptLoader.queue.
|
||||
CKEDITOR.scriptLoader.load('//code.jquery.com/jquery-1.11.0.min.js');
|
||||
CKEDITOR.scriptLoader.load('http://maps.googleapis.com/maps/api/js?libraries=places&sensor=false&callback=dummy');
|
||||
|
||||
// Add a new CKEditor plugin. Note that widgets are subclass of plugins.
|
||||
CKEDITOR.plugins.add('leaflet', {
|
||||
// Declare dependencies.
|
||||
requires: 'widget',
|
||||
|
||||
init: function(editor) {
|
||||
// Declare a new Dialog for interactive selection of
|
||||
// map parameters. It's still not bound to any widget at this moment.
|
||||
CKEDITOR.dialog.add('leaflet', this.path + 'dialogs/leaflet.js');
|
||||
|
||||
// For reusability, declare a global variable pointing to the map script path
|
||||
// that will build and render the map.
|
||||
// In JavaScript, relative path must include the leading slash.
|
||||
mapParserPath = CKEDITOR.getUrl(this.path + 'scripts/mapParser.html');
|
||||
|
||||
// Declare a new widget.
|
||||
editor.widgets.add('leaflet', {
|
||||
// Bind the widget to the Dialog command.
|
||||
dialog: 'leaflet',
|
||||
|
||||
// Declare the elements to be upcasted back.
|
||||
// Otherwise, the widget's code will be ignored.
|
||||
// Basically, we will allow all divs with 'leaflet_div' class,
|
||||
// including their alignment classes, and all iframes with
|
||||
// 'leaflet_iframe' class, and then include
|
||||
// all their attributes.
|
||||
// Read more about the Advanced Content Filter here:
|
||||
// * http://docs.ckeditor.com/#!/guide/dev_advanced_content_filter
|
||||
// * http://docs.ckeditor.com/#!/guide/plugin_sdk_integration_with_acf
|
||||
allowedContent: 'div(!leaflet_div,align-left,align-right,align-center)[*];'
|
||||
+ 'iframe(!leaflet_iframe)[*];',
|
||||
|
||||
// Declare the widget template/structure, containing the
|
||||
// important elements/attributes. This is a required property of widget.
|
||||
template:
|
||||
'<div id="" class="leaflet_div" data-lat="" data-lon="" data-width="" data-height="" ' +
|
||||
'data-zoom="" data-popup-text="" data-tile="" data-minimap="" data-alignment=""></div>',
|
||||
|
||||
// This will be executed when going from the View Mode to Source Mode.
|
||||
// This is usually used as the function to convert the widget to a
|
||||
// dummy, simpler, or equivalent textual representation.
|
||||
downcast: function(element) {
|
||||
// Note that 'element' here refers to the DIV widget.
|
||||
// Get the previously saved zoom value data attribute.
|
||||
// It will be compared to the current value in the map view.
|
||||
var zoomSaved = element.attributes["data-zoom"];
|
||||
|
||||
// Get the id of the div element.
|
||||
var divId = element.attributes["id"];
|
||||
|
||||
// Get the numeric part of divId: leaflet_div-1399121271748.
|
||||
// We'll use that number for quick fetching of target iframe.
|
||||
var iframeId = "leaflet_iframe-" + divId.substring(12);
|
||||
|
||||
// Get the zoom level's snapshot because the current user
|
||||
// might have changed it via mouse events or via the zoom bar.
|
||||
// Basically, get the zoom level of a map embedded
|
||||
// in this specific iframe and widget.
|
||||
var zoomIframe = editor.document.$.getElementById(iframeId).contentDocument.getElementById("map_container").getAttribute("data-zoom");
|
||||
|
||||
// In case there are changes in zoom level.
|
||||
if (zoomIframe != zoomSaved) {
|
||||
// Update the saved zoom value in data attribute.
|
||||
element.attributes["data-zoom"] = zoomIframe;
|
||||
|
||||
// Fetch the data attributes needed for
|
||||
// updating the full path of the map.
|
||||
var latitude = element.attributes["data-lat"];
|
||||
var longitude = element.attributes["data-lon"];
|
||||
var width = element.attributes["data-width"];
|
||||
var height = element.attributes["data-height"];
|
||||
var zoom = element.attributes["data-zoom"];
|
||||
var popUpText = element.attributes["data-popup-text"];
|
||||
var tile = element.attributes["data-tile"];
|
||||
var minimap = element.attributes["data-minimap"];
|
||||
|
||||
// Build the updated full path to the map renderer.
|
||||
var mapParserPathFull = mapParserPath + "?lat=" + latitude + "&lon=" + longitude + "&width=" + width + "&height=" + height + "&zoom=" + zoom + "&text=" + popUpText + "&tile=" + tile + "&minimap=" + minimap;
|
||||
|
||||
// Update also the iframe's 'src' attributes.
|
||||
// Updating 'data-cke-saved-src' is also required for
|
||||
// internal use of CKEditor.
|
||||
element.children[0].attributes["src"] = mapParserPathFull;
|
||||
element.children[0].attributes["data-cke-saved-src"] = mapParserPathFull;
|
||||
}
|
||||
|
||||
// Return the DOM's textual representation.
|
||||
return element;
|
||||
},
|
||||
|
||||
// Required property also for widgets, used when switching
|
||||
// from CKEditor's Source Mode to View Mode.
|
||||
// The reverse of downcast() method.
|
||||
upcast: function(element) {
|
||||
// If we encounter a div with a class of 'leaflet_div',
|
||||
// it means that it's a widget and we need to convert it properly
|
||||
// to its original structure.
|
||||
// Basically, it says to CKEditor which div is a valid widget.
|
||||
if (element.name == 'div' && element.hasClass('leaflet_div')) {
|
||||
return element;
|
||||
}
|
||||
},
|
||||
});
|
||||
|
||||
// Add the widget button in the toolbar and bind the widget command,
|
||||
// which is also bound to the Dialog command.
|
||||
// Apparently, this is required just like their plugin counterpart.
|
||||
editor.ui.addButton('leaflet', {
|
||||
label : 'Leaflet Map',
|
||||
command : 'leaflet',
|
||||
icon : this.path + 'icons/leaflet.png',
|
||||
toolbar: "insert,1"
|
||||
});
|
||||
|
||||
// Append the widget's styles when in the CKEditor edit page,
|
||||
// added for better user experience.
|
||||
// Assign or append the widget's styles depending on the existing setup.
|
||||
if (typeof editor.config.contentsCss == 'object') {
|
||||
editor.config.contentsCss.push(CKEDITOR.getUrl(this.path + 'css/contents.css'));
|
||||
}
|
||||
|
||||
else {
|
||||
editor.config.contentsCss = [editor.config.contentsCss, CKEDITOR.getUrl(this.path + 'css/contents.css')];
|
||||
}
|
||||
},
|
||||
});
|
||||
})();
|
||||
@@ -0,0 +1,22 @@
|
||||
Copyright (c) 2012, Norkart AS
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without modification, are
|
||||
permitted provided that the following conditions are met:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright notice, this list of
|
||||
conditions and the following disclaimer.
|
||||
|
||||
2. Redistributions in binary form must reproduce the above copyright notice, this list
|
||||
of conditions and the following disclaimer in the documentation and/or other materials
|
||||
provided with the distribution.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
|
||||
EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
|
||||
TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
@@ -0,0 +1,37 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>MiniMap Demo</title>
|
||||
<meta charset="utf-8" />
|
||||
|
||||
<link rel="stylesheet" href="./fullscreen.css" />
|
||||
|
||||
<!-- Leaflet -->
|
||||
<link rel="stylesheet" href="http://cdn.leafletjs.com/leaflet-0.7.1/leaflet.css" />
|
||||
<!--[if lte IE 8]><link rel="stylesheet" href="http://cdn.leafletjs.com/leaflet-0.7.1/leaflet.ie.css" /><![endif]-->
|
||||
<script src="http://cdn.leafletjs.com/leaflet-0.7.1/leaflet-src.js" type="text/javascript"></script>
|
||||
|
||||
<!-- Leaflet Plugins -->
|
||||
<link rel="stylesheet" href="../src/Control.MiniMap.css" />
|
||||
<script src="../src/Control.MiniMap.js" type="text/javascript"></script>
|
||||
|
||||
</head>
|
||||
<body>
|
||||
<div id="map" ></div>
|
||||
|
||||
<script type="text/javascript">
|
||||
|
||||
var map = new L.Map('map');
|
||||
var osmUrl='http://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png';
|
||||
var osmAttrib='Map data © OpenStreetMap contributors';
|
||||
var osm = new L.TileLayer(osmUrl, {minZoom: 5, maxZoom: 18, attribution: osmAttrib});
|
||||
|
||||
map.addLayer(osm);
|
||||
map.setView(new L.LatLng(59.92448055859924, 10.758276373601069),10);
|
||||
|
||||
//Plugin magic goes here! Note that you cannot use the same layer object again, as that will confuse the two map controls
|
||||
var osm2 = new L.TileLayer(osmUrl, {minZoom: 0, maxZoom: 13, attribution: osmAttrib });
|
||||
var miniMap = new L.Control.MiniMap(osm2, { toggleDisplay: true }).addTo(map);
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,40 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>MiniMap Demo</title>
|
||||
<meta charset="utf-8" />
|
||||
|
||||
<link rel="stylesheet" href="./fullscreen.css" />
|
||||
|
||||
<!-- Leaflet -->
|
||||
<link rel="stylesheet" href="http://cdn.leafletjs.com/leaflet-0.7.1/leaflet.css" />
|
||||
<!--[if lte IE 8]><link rel="stylesheet" href="http://cdn.leafletjs.com/leaflet-0.7.1/leaflet.ie.css" /><![endif]-->
|
||||
<script src="http://cdn.leafletjs.com/leaflet-0.7.1/leaflet-src.js" type="text/javascript"></script>
|
||||
|
||||
<!-- Leaflet Plugins -->
|
||||
<link rel="stylesheet" href="../src/Control.MiniMap.css" />
|
||||
<script src="../src/Control.MiniMap.js" type="text/javascript"></script>
|
||||
|
||||
</head>
|
||||
<body>
|
||||
<div id="map" ></div>
|
||||
|
||||
<script type="text/javascript">
|
||||
|
||||
var map = new L.Map('map');
|
||||
var osmUrl='http://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png';
|
||||
var osmAttrib='Map data © OpenStreetMap contributors';
|
||||
var osm = new L.TileLayer(osmUrl, {minZoom: 5, maxZoom: 18, attribution: osmAttrib});
|
||||
|
||||
map.addLayer(osm);
|
||||
map.setView(new L.LatLng(59.92448055859924, 10.758276373601069),10);
|
||||
|
||||
//Plugin magic goes here! Note that you cannot use the same layer object again, as that will confuse the two map controls
|
||||
var osm2 = new L.TileLayer(osmUrl, {minZoom: 0, maxZoom: 13, attribution: osmAttrib });
|
||||
|
||||
var rect1 = {color: "#ff1100", weight: 3};
|
||||
var rect2 = {color: "#0000AA", weight: 1, opacity:0, fillOpacity:0};
|
||||
var miniMap = new L.Control.MiniMap(osm2, { toggleDisplay: true, aimingRectOptions : rect1, shadowRectOptions: rect2}).addTo(map);
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,37 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>MiniMap Fixed Zoom Level Demo</title>
|
||||
<meta charset="utf-8" />
|
||||
|
||||
<link rel="stylesheet" href="./fullscreen.css" />
|
||||
|
||||
<!-- Leaflet -->
|
||||
<link rel="stylesheet" href="http://cdn.leafletjs.com/leaflet-0.7.1/leaflet.css" />
|
||||
<!--[if lte IE 8]><link rel="stylesheet" href="http://cdn.leafletjs.com/leaflet-0.7.1/leaflet.ie.css" /><![endif]-->
|
||||
<script src="http://cdn.leafletjs.com/leaflet-0.7.1/leaflet.js" type="text/javascript"></script>
|
||||
|
||||
<!-- Leaflet Plugins -->
|
||||
<link rel="stylesheet" href="../src/Control.MiniMap.css" />
|
||||
<script src="../src/Control.MiniMap.js" type="text/javascript"></script>
|
||||
|
||||
</head>
|
||||
<body>
|
||||
<div id="map" ></div>
|
||||
|
||||
<script type="text/javascript">
|
||||
|
||||
var map = new L.Map('map');
|
||||
var osmUrl='http://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png';
|
||||
var osmAttrib='Map data © OpenStreetMap contributors';
|
||||
var osm = new L.TileLayer(osmUrl, {minZoom: 2, maxZoom: 18, attribution: osmAttrib});
|
||||
|
||||
map.addLayer(osm);
|
||||
map.setView(new L.LatLng(59.92448055859924, 10.758276373601069),10);
|
||||
|
||||
//Plugin magic goes here! Note that you cannot use the same layer object again, as that will confuse the two map controls
|
||||
var osm2 = new L.TileLayer(osmUrl, {minZoom: 2, maxZoom: 18, attribution: osmAttrib});
|
||||
var miniMap = new L.Control.MiniMap(osm2, {zoomLevelFixed: 5, autoToggleDisplay: true}).addTo(map);
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,40 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>MiniMap Demo</title>
|
||||
<meta charset="utf-8" />
|
||||
|
||||
<link rel="stylesheet" href="./fullscreen.css" />
|
||||
|
||||
<!-- Leaflet -->
|
||||
<link rel="stylesheet" href="http://cdn.leafletjs.com/leaflet-0.7.1/leaflet.css" />
|
||||
<!--[if lte IE 8]><link rel="stylesheet" href="http://cdn.leafletjs.com/leaflet-0.7.1/leaflet.ie.css" /><![endif]-->
|
||||
<script src="http://cdn.leafletjs.com/leaflet-0.7.1/leaflet.js" type="text/javascript"></script>
|
||||
|
||||
<!-- Leaflet Plugins -->
|
||||
<link rel="stylesheet" href="../src/Control.MiniMap.css" />
|
||||
<script src="../src/Control.MiniMap.js" type="text/javascript"></script>
|
||||
|
||||
</head>
|
||||
<body>
|
||||
<div id="map" ></div>
|
||||
|
||||
<script type="text/javascript">
|
||||
|
||||
var map = new L.Map('map');
|
||||
var osmUrl='http://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png';
|
||||
var osmAttrib='Map data © OpenStreetMap contributors';
|
||||
var osm = new L.TileLayer(osmUrl, {minZoom: 2, maxZoom: 18, attribution: osmAttrib});
|
||||
|
||||
map.addLayer(osm);
|
||||
map.setView(new L.LatLng(59.92448055859924, 10.758276373601069),10);
|
||||
|
||||
//Plugin magic goes here! Note that you cannot use the same layer object again, as that will confuse the two map controls
|
||||
var osm2 = new L.TileLayer(osmUrl, {minZoom: 2, maxZoom: 18, attribution: osmAttrib});
|
||||
var miniMap = new L.Control.MiniMap(osm2, {
|
||||
width: 250,
|
||||
height: 250
|
||||
}).addTo(map);
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,61 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>MiniMap Demo</title>
|
||||
<meta charset="utf-8" />
|
||||
|
||||
<link rel="stylesheet" href="./fullscreen.css" />
|
||||
|
||||
<!-- Leaflet -->
|
||||
<link rel="stylesheet" href="http://cdn.leafletjs.com/leaflet-0.7.1/leaflet.css" />
|
||||
<!--[if lte IE 8]><link rel="stylesheet" href="http://cdn.leafletjs.com/leaflet-0.7.1/leaflet.ie.css" /><![endif]-->
|
||||
<script src="http://cdn.leafletjs.com/leaflet-0.7.1/leaflet-src.js" type="text/javascript"></script>
|
||||
|
||||
<!-- Leaflet Plugins -->
|
||||
<link rel="stylesheet" href="../src/Control.MiniMap.css" />
|
||||
<script src="../src/Control.MiniMap.js" type="text/javascript"></script>
|
||||
|
||||
<!-- Extra data source -->
|
||||
<script src="local_pubs_restaurant_norway.js" type="text/javascript"></script>
|
||||
|
||||
</head>
|
||||
<body>
|
||||
<div id="map" ></div>
|
||||
|
||||
<script type="text/javascript">
|
||||
|
||||
var map = new L.Map('map');
|
||||
var osmUrl='http://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png';
|
||||
var osmAttrib='Map data © OpenStreetMap contributors';
|
||||
var osm = new L.TileLayer(osmUrl, {minZoom: 5, maxZoom: 18, attribution: osmAttrib});
|
||||
|
||||
function createPopUp(feature, layer) {
|
||||
var string = "";
|
||||
for (var k in feature.properties) {
|
||||
string += k + " : " + feature.properties[k] + "<br>"
|
||||
}
|
||||
layer.bindPopup(string);
|
||||
};
|
||||
|
||||
var pubs1 = L.geoJson(pubsGeoJSON, {
|
||||
onEachFeature: createPopUp
|
||||
});
|
||||
|
||||
map.addLayer(osm);
|
||||
map.addLayer(pubs1);
|
||||
map.setView(new L.LatLng(59.92448055859924, 10.758276373601069),10);
|
||||
|
||||
//Plugin magic goes here! Note that you cannot use the same layer object again, as that will confuse the two map controls. This also goes for the GeoJSON layer!
|
||||
var osm2 = new L.TileLayer(osmUrl, {minZoom: 0, maxZoom: 13, attribution: osmAttrib });
|
||||
var pubs2 = L.geoJson(pubsGeoJSON, {
|
||||
pointToLayer: function (featuredata, latlng) {
|
||||
return new L.CircleMarker(latlng, {radius: 2});
|
||||
}
|
||||
});
|
||||
|
||||
var layers = new L.LayerGroup([osm2, pubs2]);
|
||||
|
||||
var miniMap = new L.Control.MiniMap(layers, { toggleDisplay: true }).addTo(map);
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,37 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>MiniMap Test - Same zoom limits</title>
|
||||
<meta charset="utf-8" />
|
||||
|
||||
<link rel="stylesheet" href="./fullscreen.css" />
|
||||
|
||||
<!-- Leaflet -->
|
||||
<link rel="stylesheet" href="http://cdn.leafletjs.com/leaflet-0.7.1/leaflet.css" />
|
||||
<!--[if lte IE 8]><link rel="stylesheet" href="http://cdn.leafletjs.com/leaflet-0.7.1/leaflet.ie.css" /><![endif]-->
|
||||
<script src="http://cdn.leafletjs.com/leaflet-0.7.1/leaflet-src.js" type="text/javascript"></script>
|
||||
|
||||
<!-- Leaflet Plugins -->
|
||||
<link rel="stylesheet" href="../src/Control.MiniMap.css" />
|
||||
<script src="../src/Control.MiniMap.js" type="text/javascript"></script>
|
||||
|
||||
</head>
|
||||
<body>
|
||||
<div id="map" ></div>
|
||||
|
||||
<script type="text/javascript">
|
||||
|
||||
var map = new L.Map('map');
|
||||
var osmUrl='http://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png';
|
||||
var osmAttrib='Map data © OpenStreetMap contributors';
|
||||
var osm = new L.TileLayer(osmUrl, {minZoom: 0, maxZoom: 18, attribution: osmAttrib});
|
||||
|
||||
map.addLayer(osm);
|
||||
map.setView(new L.LatLng(59.92448055859924, 10.758276373601069),2);
|
||||
|
||||
//Plugin magic goes here! Note that you cannot use the same layer object again, as that will confuse the two map controls
|
||||
var osm2 = new L.TileLayer(osmUrl, {minZoom: 0, maxZoom: 18, attribution: osmAttrib });
|
||||
var miniMap = new L.Control.MiniMap(osm2, { toggleDisplay: true }).addTo(map);
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,37 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>MiniMap Demo</title>
|
||||
<meta charset="utf-8" />
|
||||
|
||||
<link rel="stylesheet" href="./fullscreen.css" />
|
||||
|
||||
<!-- Leaflet -->
|
||||
<link rel="stylesheet" href="http://cdn.leafletjs.com/leaflet-0.7.1/leaflet.css" />
|
||||
<!--[if lte IE 8]><link rel="stylesheet" href="http://cdn.leafletjs.com/leaflet-0.7.1/leaflet.ie.css" /><![endif]-->
|
||||
<script src="http://cdn.leafletjs.com/leaflet-0.7.1/leaflet-src.js" type="text/javascript"></script>
|
||||
|
||||
<!-- Leaflet Plugins -->
|
||||
<link rel="stylesheet" href="../src/Control.MiniMap.css" />
|
||||
<script src="../src/Control.MiniMap.js" type="text/javascript"></script>
|
||||
|
||||
</head>
|
||||
<body>
|
||||
<div id="map" ></div>
|
||||
|
||||
<script type="text/javascript">
|
||||
|
||||
var map = new L.Map('map');
|
||||
var osmUrl='http://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png';
|
||||
var osmAttrib='Map data © OpenStreetMap contributors';
|
||||
var osm = new L.TileLayer(osmUrl, {minZoom: 5, maxZoom: 18, attribution: osmAttrib});
|
||||
|
||||
map.addLayer(osm);
|
||||
map.setView(new L.LatLng(59.92448055859924, 10.758276373601069),10);
|
||||
|
||||
//Plugin magic goes here! Note that you cannot use the same layer object again, as that will confuse the two map controls
|
||||
var osm2 = new L.TileLayer(osmUrl, {minZoom: 0, maxZoom: 13, attribution: osmAttrib });
|
||||
var miniMap = new L.Control.MiniMap(osm2, { toggleDisplay: true }).addTo(map);
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,8 @@
|
||||
body {
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
}
|
||||
html, body, #map {
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,25 @@
|
||||
{
|
||||
"name": "leaflet-minimap",
|
||||
"version": "1.0.0",
|
||||
"author": "Norkart AS",
|
||||
"description": "A plugin for Leaflet that provides a minimap in the corner of the map view.",
|
||||
"license": "BSD-2-Clause",
|
||||
"readmeFilename": "README.md",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/Norkart/Leaflet-MiniMap.git"
|
||||
},
|
||||
"homepage": "https://github.com/Norkart/Leaflet-MiniMap",
|
||||
"bugs": {
|
||||
"url": "https://github.com/Norkart/Leaflet-MiniMap/issues"
|
||||
},
|
||||
"dependencies": {
|
||||
"leaflet": ">=0.5.0"
|
||||
},
|
||||
"keywords": [
|
||||
"maps",
|
||||
"leaflet",
|
||||
"client",
|
||||
"minimap"
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
# Leaflet.MiniMap
|
||||
|
||||
Leaflet.MiniMap is a simple minimap control that you can drop into your leaflet map, and it will create a small map in the corner which shows the same as the main map with a set zoom offset. (By default it is -5.)
|
||||
|
||||
## Using the MiniMap control
|
||||
|
||||
The control can be inserted in two lines: First you have to construct a layer for it to use, and then you create and attach the minimap control. Don't reuse the layer you added to the main map, strange behaviour will ensue! Alternatively, you can pass in a LayerGroup with multiple layers (for example with overlays or suitably themed markers). Marker layers can't be reused either. (See issue #52 for a discussion of syncronising marker layers.)
|
||||
|
||||
From the [example](http://norkart.github.com/Leaflet-MiniMap/example.html):
|
||||
|
||||
var osm2 = new L.TileLayer(osmUrl, {minZoom: 0, maxZoom: 13, attribution: osmAttrib});
|
||||
var miniMap = new L.Control.MiniMap(osm2).addTo(map);
|
||||
|
||||
As the minimap control inherits from leaflet's control, positioning is handled automatically by leaflet. However, you can still style the minimap and set its size by modifying the css file.
|
||||
|
||||
**Note:** Leaflet version 0.5 or higher is required.
|
||||
|
||||
## Available Options
|
||||
The mini map uses options which can be set in the same way as other leaflet options, and these are the available options:
|
||||
|
||||
`position:` The standard Leaflet.Control position parameter, used like all the other controls. Defaults to 'bottomright'.
|
||||
|
||||
`width:` The width of the minimap in pixels. Defaults to 150.
|
||||
|
||||
`height:` The height of the minimap in pixels. Defaults to 150.
|
||||
|
||||
`zoomLevelOffset:` The offset applied to the zoom in the minimap compared to the zoom of the main map. Can be positive or negative, defaults to -5.
|
||||
|
||||
`zoomLevelFixed:` Overrides the offset to apply a fixed zoom level to the minimap regardless of the main map zoom. Set it to any valid zoom level, if unset `zoomLevelOffset` is used instead.
|
||||
|
||||
`zoomAnimation:` Sets whether the minimap should have an animated zoom. (Will cause it to lag a bit after the movement of the main map.) Defaults to false.
|
||||
|
||||
`toggleDisplay:` Sets whether the minimap should have a button to minimise it. Defaults to false.
|
||||
|
||||
`autoToggleDisplay:` Sets whether the minimap should hide automatically if the parent map bounds does not fit within the minimap bounds. Especially useful when 'zoomLevelFixed' is set.
|
||||
|
||||
`aimingRectOptions:` Sets the style of the aiming rectangle by passing in a [Path.Options object](http://leafletjs.com/reference.html#path-options). (Clickable will always be overridden and set to false.)
|
||||
|
||||
`shadowRectOptions:` Sets the style of the aiming shadow rectangle by passing in a [Path.Options object](http://leafletjs.com/reference.html#path-options). (Clickable will always be overridden and set to false.)
|
||||
|
||||
###Translation strings
|
||||
|
||||
These are not passed as options, but are overridden in a subclass. To do general translation overrides take a look at the german example sourcefile.
|
||||
|
||||
`hideText:` Text-String to be displayed as Tooltip when hovering over the toggle button on the MiniMap and it is visible.
|
||||
|
||||
`showText:` Text-String to be displayed as Tooltip when hovering over the toggle button on the MiniMap and it is hidden.
|
||||
@@ -0,0 +1,4 @@
|
||||
L.extend(L.Control.MiniMap.prototype,{
|
||||
hideText: 'Miniaturkarte ausblenden',
|
||||
showText: 'Miniaturkarte einblenden'
|
||||
});
|
||||
@@ -0,0 +1,43 @@
|
||||
.leaflet-control-minimap {
|
||||
border:solid rgba(255, 255, 255, 1.0) 4px;
|
||||
box-shadow: 0 1px 5px rgba(0,0,0,0.65);
|
||||
border-radius: 3px;
|
||||
background: #f8f8f9;
|
||||
transition: all .2s;
|
||||
}
|
||||
|
||||
.leaflet-control-minimap a {
|
||||
background-color: rgba(255, 255, 255, 1.0);
|
||||
background-repeat: no-repeat;
|
||||
z-index: 99999;
|
||||
transition: all .2s;
|
||||
border-radius: 3px 0px 0px 0px;
|
||||
}
|
||||
|
||||
.leaflet-control-minimap a.minimized {
|
||||
-webkit-transform: rotate(180deg);
|
||||
transform: rotate(180deg);
|
||||
border-radius: 0px;
|
||||
}
|
||||
|
||||
.leaflet-control-minimap-toggle-display {
|
||||
background-image: url("images/toggle.png");
|
||||
height: 19px;
|
||||
width: 19px;
|
||||
position: absolute;
|
||||
bottom: 0;
|
||||
right: 0;
|
||||
}
|
||||
|
||||
/* Old IE */
|
||||
.leaflet-oldie .leaflet-control-minimap {
|
||||
border: 1px solid #999;
|
||||
}
|
||||
|
||||
.leaflet-oldie .leaflet-control-minimap a {
|
||||
background-color: #fff;
|
||||
}
|
||||
|
||||
.leaflet-oldie .leaflet-control-minimap a.minimized {
|
||||
filter: progid:DXImageTransform.Microsoft.BasicImage(rotation=2);
|
||||
}
|
||||
@@ -0,0 +1,270 @@
|
||||
L.Control.MiniMap = L.Control.extend({
|
||||
options: {
|
||||
position: 'bottomright',
|
||||
toggleDisplay: false,
|
||||
zoomLevelOffset: -5,
|
||||
zoomLevelFixed: false,
|
||||
zoomAnimation: false,
|
||||
autoToggleDisplay: false,
|
||||
width: 150,
|
||||
height: 150,
|
||||
aimingRectOptions: {color: "#ff7800", weight: 1, clickable: false},
|
||||
shadowRectOptions: {color: "#000000", weight: 1, clickable: false, opacity:0, fillOpacity:0}
|
||||
},
|
||||
|
||||
hideText: 'Hide MiniMap',
|
||||
|
||||
showText: 'Show MiniMap',
|
||||
|
||||
//layer is the map layer to be shown in the minimap
|
||||
initialize: function (layer, options) {
|
||||
L.Util.setOptions(this, options);
|
||||
//Make sure the aiming rects are non-clickable even if the user tries to set them clickable (most likely by forgetting to specify them false)
|
||||
this.options.aimingRectOptions.clickable = false;
|
||||
this.options.shadowRectOptions.clickable = false;
|
||||
this._layer = layer;
|
||||
},
|
||||
|
||||
onAdd: function (map) {
|
||||
|
||||
this._mainMap = map;
|
||||
|
||||
//Creating the container and stopping events from spilling through to the main map.
|
||||
this._container = L.DomUtil.create('div', 'leaflet-control-minimap');
|
||||
this._container.style.width = this.options.width + 'px';
|
||||
this._container.style.height = this.options.height + 'px';
|
||||
L.DomEvent.disableClickPropagation(this._container);
|
||||
L.DomEvent.on(this._container, 'mousewheel', L.DomEvent.stopPropagation);
|
||||
|
||||
|
||||
this._miniMap = new L.Map(this._container,
|
||||
{
|
||||
attributionControl: false,
|
||||
zoomControl: false,
|
||||
zoomAnimation: this.options.zoomAnimation,
|
||||
autoToggleDisplay: this.options.autoToggleDisplay,
|
||||
touchZoom: !this.options.zoomLevelFixed,
|
||||
scrollWheelZoom: !this.options.zoomLevelFixed,
|
||||
doubleClickZoom: !this.options.zoomLevelFixed,
|
||||
boxZoom: !this.options.zoomLevelFixed,
|
||||
crs: map.options.crs
|
||||
});
|
||||
|
||||
this._miniMap.addLayer(this._layer);
|
||||
|
||||
//These bools are used to prevent infinite loops of the two maps notifying each other that they've moved.
|
||||
this._mainMapMoving = false;
|
||||
this._miniMapMoving = false;
|
||||
|
||||
//Keep a record of this to prevent auto toggling when the user explicitly doesn't want it.
|
||||
this._userToggledDisplay = false;
|
||||
this._minimized = false;
|
||||
|
||||
if (this.options.toggleDisplay) {
|
||||
this._addToggleButton();
|
||||
}
|
||||
|
||||
this._miniMap.whenReady(L.Util.bind(function () {
|
||||
this._aimingRect = L.rectangle(this._mainMap.getBounds(), this.options.aimingRectOptions).addTo(this._miniMap);
|
||||
this._shadowRect = L.rectangle(this._mainMap.getBounds(), this.options.shadowRectOptions).addTo(this._miniMap);
|
||||
this._mainMap.on('moveend', this._onMainMapMoved, this);
|
||||
this._mainMap.on('move', this._onMainMapMoving, this);
|
||||
this._miniMap.on('movestart', this._onMiniMapMoveStarted, this);
|
||||
this._miniMap.on('move', this._onMiniMapMoving, this);
|
||||
this._miniMap.on('moveend', this._onMiniMapMoved, this);
|
||||
}, this));
|
||||
|
||||
return this._container;
|
||||
},
|
||||
|
||||
addTo: function (map) {
|
||||
L.Control.prototype.addTo.call(this, map);
|
||||
this._miniMap.setView(this._mainMap.getCenter(), this._decideZoom(true));
|
||||
this._setDisplay(this._decideMinimized());
|
||||
return this;
|
||||
},
|
||||
|
||||
onRemove: function (map) {
|
||||
this._mainMap.off('moveend', this._onMainMapMoved, this);
|
||||
this._mainMap.off('move', this._onMainMapMoving, this);
|
||||
this._miniMap.off('moveend', this._onMiniMapMoved, this);
|
||||
|
||||
this._miniMap.removeLayer(this._layer);
|
||||
},
|
||||
|
||||
_addToggleButton: function () {
|
||||
this._toggleDisplayButton = this.options.toggleDisplay ? this._createButton(
|
||||
'', this.hideText, 'leaflet-control-minimap-toggle-display', this._container, this._toggleDisplayButtonClicked, this) : undefined;
|
||||
},
|
||||
|
||||
_createButton: function (html, title, className, container, fn, context) {
|
||||
var link = L.DomUtil.create('a', className, container);
|
||||
link.innerHTML = html;
|
||||
link.href = '#';
|
||||
link.title = title;
|
||||
|
||||
var stop = L.DomEvent.stopPropagation;
|
||||
|
||||
L.DomEvent
|
||||
.on(link, 'click', stop)
|
||||
.on(link, 'mousedown', stop)
|
||||
.on(link, 'dblclick', stop)
|
||||
.on(link, 'click', L.DomEvent.preventDefault)
|
||||
.on(link, 'click', fn, context);
|
||||
|
||||
return link;
|
||||
},
|
||||
|
||||
_toggleDisplayButtonClicked: function () {
|
||||
this._userToggledDisplay = true;
|
||||
if (!this._minimized) {
|
||||
this._minimize();
|
||||
this._toggleDisplayButton.title = this.showText;
|
||||
}
|
||||
else {
|
||||
this._restore();
|
||||
this._toggleDisplayButton.title = this.hideText;
|
||||
}
|
||||
},
|
||||
|
||||
_setDisplay: function (minimize) {
|
||||
if (minimize != this._minimized) {
|
||||
if (!this._minimized) {
|
||||
this._minimize();
|
||||
}
|
||||
else {
|
||||
this._restore();
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
_minimize: function () {
|
||||
// hide the minimap
|
||||
if (this.options.toggleDisplay) {
|
||||
this._container.style.width = '19px';
|
||||
this._container.style.height = '19px';
|
||||
this._toggleDisplayButton.className += ' minimized';
|
||||
}
|
||||
else {
|
||||
this._container.style.display = 'none';
|
||||
}
|
||||
this._minimized = true;
|
||||
},
|
||||
|
||||
_restore: function () {
|
||||
if (this.options.toggleDisplay) {
|
||||
this._container.style.width = this.options.width + 'px';
|
||||
this._container.style.height = this.options.height + 'px';
|
||||
this._toggleDisplayButton.className = this._toggleDisplayButton.className
|
||||
.replace(/(?:^|\s)minimized(?!\S)/g, '');
|
||||
}
|
||||
else {
|
||||
this._container.style.display = 'block';
|
||||
}
|
||||
this._minimized = false;
|
||||
},
|
||||
|
||||
_onMainMapMoved: function (e) {
|
||||
if (!this._miniMapMoving) {
|
||||
this._mainMapMoving = true;
|
||||
this._miniMap.setView(this._mainMap.getCenter(), this._decideZoom(true));
|
||||
this._setDisplay(this._decideMinimized());
|
||||
} else {
|
||||
this._miniMapMoving = false;
|
||||
}
|
||||
this._aimingRect.setBounds(this._mainMap.getBounds());
|
||||
},
|
||||
|
||||
_onMainMapMoving: function (e) {
|
||||
this._aimingRect.setBounds(this._mainMap.getBounds());
|
||||
},
|
||||
|
||||
_onMiniMapMoveStarted:function (e) {
|
||||
var lastAimingRect = this._aimingRect.getBounds();
|
||||
var sw = this._miniMap.latLngToContainerPoint(lastAimingRect.getSouthWest());
|
||||
var ne = this._miniMap.latLngToContainerPoint(lastAimingRect.getNorthEast());
|
||||
this._lastAimingRectPosition = {sw:sw,ne:ne};
|
||||
},
|
||||
|
||||
_onMiniMapMoving: function (e) {
|
||||
if (!this._mainMapMoving && this._lastAimingRectPosition) {
|
||||
this._shadowRect.setBounds(new L.LatLngBounds(this._miniMap.containerPointToLatLng(this._lastAimingRectPosition.sw),this._miniMap.containerPointToLatLng(this._lastAimingRectPosition.ne)));
|
||||
this._shadowRect.setStyle({opacity:1,fillOpacity:0.3});
|
||||
}
|
||||
},
|
||||
|
||||
_onMiniMapMoved: function (e) {
|
||||
if (!this._mainMapMoving) {
|
||||
this._miniMapMoving = true;
|
||||
this._mainMap.setView(this._miniMap.getCenter(), this._decideZoom(false));
|
||||
this._shadowRect.setStyle({opacity:0,fillOpacity:0});
|
||||
} else {
|
||||
this._mainMapMoving = false;
|
||||
}
|
||||
},
|
||||
|
||||
_decideZoom: function (fromMaintoMini) {
|
||||
if (!this.options.zoomLevelFixed) {
|
||||
if (fromMaintoMini)
|
||||
return this._mainMap.getZoom() + this.options.zoomLevelOffset;
|
||||
else {
|
||||
var currentDiff = this._miniMap.getZoom() - this._mainMap.getZoom();
|
||||
var proposedZoom = this._miniMap.getZoom() - this.options.zoomLevelOffset;
|
||||
var toRet;
|
||||
|
||||
if (currentDiff > this.options.zoomLevelOffset && this._mainMap.getZoom() < this._miniMap.getMinZoom() - this.options.zoomLevelOffset) {
|
||||
//This means the miniMap is zoomed out to the minimum zoom level and can't zoom any more.
|
||||
if (this._miniMap.getZoom() > this._lastMiniMapZoom) {
|
||||
//This means the user is trying to zoom in by using the minimap, zoom the main map.
|
||||
toRet = this._mainMap.getZoom() + 1;
|
||||
//Also we cheat and zoom the minimap out again to keep it visually consistent.
|
||||
this._miniMap.setZoom(this._miniMap.getZoom() -1);
|
||||
} else {
|
||||
//Either the user is trying to zoom out past the mini map's min zoom or has just panned using it, we can't tell the difference.
|
||||
//Therefore, we ignore it!
|
||||
toRet = this._mainMap.getZoom();
|
||||
}
|
||||
} else {
|
||||
//This is what happens in the majority of cases, and always if you configure the min levels + offset in a sane fashion.
|
||||
toRet = proposedZoom;
|
||||
}
|
||||
this._lastMiniMapZoom = this._miniMap.getZoom();
|
||||
return toRet;
|
||||
}
|
||||
} else {
|
||||
if (fromMaintoMini)
|
||||
return this.options.zoomLevelFixed;
|
||||
else
|
||||
return this._mainMap.getZoom();
|
||||
}
|
||||
},
|
||||
|
||||
_decideMinimized: function () {
|
||||
if (this._userToggledDisplay) {
|
||||
return this._minimized;
|
||||
}
|
||||
|
||||
if (this.options.autoToggleDisplay) {
|
||||
if (this._mainMap.getBounds().contains(this._miniMap.getBounds())) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
return this._minimized;
|
||||
}
|
||||
});
|
||||
|
||||
L.Map.mergeOptions({
|
||||
miniMapControl: false
|
||||
});
|
||||
|
||||
L.Map.addInitHook(function () {
|
||||
if (this.options.miniMapControl) {
|
||||
this.miniMapControl = (new L.Control.MiniMap()).addTo(this);
|
||||
}
|
||||
});
|
||||
|
||||
L.control.minimap = function (options) {
|
||||
return new L.Control.MiniMap(options);
|
||||
};
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 345 B |
@@ -0,0 +1,14 @@
|
||||
window2 = window.frames[0];
|
||||
console.log(window.frames[0]);
|
||||
|
||||
(function (window2) {
|
||||
var window = window2;
|
||||
var document = window.document;
|
||||
|
||||
console.log('lamang-lupa2');
|
||||
console.log(window);
|
||||
//console.log(window);
|
||||
//console.log(window.document);
|
||||
console.log(document);
|
||||
console.log('lamang-labas');
|
||||
})(window2)
|
||||
@@ -0,0 +1 @@
|
||||
preview/highlightjs/highlight.pack.js
|
||||
@@ -0,0 +1,40 @@
|
||||
{
|
||||
|
||||
// environment
|
||||
"browser": true,
|
||||
"node": false,
|
||||
"strict": true,
|
||||
|
||||
"globals": {
|
||||
"L": true
|
||||
},
|
||||
|
||||
// code style
|
||||
"bitwise": true,
|
||||
"camelcase": true,
|
||||
"curly": true,
|
||||
"eqeqeq": true,
|
||||
"forin": false,
|
||||
"immed": true,
|
||||
"latedef": true,
|
||||
"newcap": true,
|
||||
"noarg": true,
|
||||
"noempty": true,
|
||||
"nonew": true,
|
||||
"undef": true,
|
||||
"unused": true,
|
||||
"quotmark": "single",
|
||||
|
||||
// whitespace
|
||||
"indent": 4,
|
||||
"trailing": true,
|
||||
"white": true,
|
||||
"smarttabs": true,
|
||||
"maxlen": 120
|
||||
|
||||
// code simplicity - not enforced but nice to check from time to time
|
||||
// "maxstatements": 20,
|
||||
// "maxcomplexity": 5
|
||||
// "maxparams": 4,
|
||||
// "maxdepth": 4
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
So you want to add a layer?
|
||||
=======
|
||||
|
||||
Yay! go add it to the leaflet-providers.js as long as it follows the following
|
||||
rules:
|
||||
|
||||
- Don't violate a providers TOS (if it exists, include a link to it)
|
||||
- Don't pre-populate api keys with working keys.
|
||||
- It should be a basic tile source, no exteral libraries etc.
|
||||
- The owner hasn't asked us to remove it (hasn't happened yet)
|
||||
@@ -0,0 +1,75 @@
|
||||
Leaflet-providers
|
||||
=================
|
||||
An extension to [Leaflet](http://leafletjs.com/) that contains configurations for various free tile providers.
|
||||
|
||||
# Usage
|
||||
Leaflet-providers [providers](#providers) are refered to with a `provider[.<variant>]`-string. Let's say you want to add the nice [Watercolor](http://maps.stamen.com/#watercolor/) style from Stamen to your map, you pass `Stamen.Watercolor` to the `L.tileLayer.provider`-constructor, which will return a [L.TileLayer](http://leafletjs.com/reference.html#tilelayer) instance for Stamens Watercolor tile layer.
|
||||
|
||||
```Javascript
|
||||
// add Stamen Watercolor to map.
|
||||
L.tileLayer.provider('Stamen.Watercolor').addTo(map);
|
||||
```
|
||||
|
||||
# Providers
|
||||
|
||||
Leaflet-providers provides tile layers from different providers, including *OpenStreetMap*, *MapQuestOpen*, *Stamen*, *Esri* and *OpenWeatherMap*. The full listing of free to use layers can be [previewed](http://leaflet-extras.github.io/leaflet-providers/preview/index.html). The page will show you the name to use with `leaflet-providers.js` and the code to use it without dependencies.
|
||||
|
||||
## Providers requiring registration
|
||||
|
||||
In addition to the providers you are free to use, we support some layers which require registration.
|
||||
|
||||
### Nokia.
|
||||
|
||||
In order to use Nokia basemaps, you must [register](https://developer.here.com/web/guest/myapps). With your `devID` and `appID` specified in the options, the available layers are:
|
||||
|
||||
* Nokia.normalDay
|
||||
* Nokia.normalGreyDay
|
||||
* Nokia.satelliteNoLabelsDay
|
||||
* Nokia.satelliteYesLabelsDay
|
||||
* Nokia.terrainDay
|
||||
|
||||
For example:
|
||||
```Javascript
|
||||
L.tileLayer.provider('Nokia.terrainDay', {
|
||||
devID: 'insert ID here',
|
||||
appId: 'insert ID here'
|
||||
}).addTo(map);
|
||||
```
|
||||
|
||||
### Mapbox
|
||||
|
||||
In order to use Mapbox maps, you must [register](https://tiles.mapbox.com/signup). If your user name is `YourName` and your map is called `MyMap` you can add it with
|
||||
```JavaScript
|
||||
L.tileLayer.provider('MapBox.YourName.MyMap');
|
||||
```
|
||||
|
||||
### Esri/ArcGIS
|
||||
|
||||
In order to use ArcGIS maps, you must [register](https://developers.arcgis.com/en/sign-up/) and abide by the [terms of service](https://developers.arcgis.com/en/terms/). Available layers are...
|
||||
|
||||
* Esri.WorldStreetMap
|
||||
* Esri.DeLorme
|
||||
* Esri.WorldTopoMap
|
||||
* Esri.WorldImagery
|
||||
* Esri.WorldTerrain
|
||||
* Esri.WorldShadedRelief
|
||||
* Esri.WorldPhysical
|
||||
* Esri.OceanBasemap
|
||||
* Esri.NatGeoWorldMap
|
||||
* Esri.WorldGrayCanvas
|
||||
|
||||
# Goodies
|
||||
|
||||
An other little goodie this library provides is a prefilled layer control, so you can just provide an array of strings:
|
||||
|
||||
```JavaScript
|
||||
var baseLayers = ['Stamen.Watercolor', 'OpenStreetMap.Mapnik'],
|
||||
overlays = ['OpenWeatherMap.Clouds'];
|
||||
|
||||
var layerControl = L.control.layers.provided(baseLayers, overlays).addTo(map);
|
||||
|
||||
// you can still add your own afterwards with
|
||||
layerControl.addBaseLayer(layer, name);
|
||||
```
|
||||
|
||||
This work was inspired from <https://gist.github.com/1804938>, and originally created by [Stefan Seelmann](https://github.com/seelmann).
|
||||
@@ -0,0 +1,22 @@
|
||||
{
|
||||
"name": "leaflet-providers",
|
||||
"version": "1.0.3",
|
||||
"homepage": "https://github.com/leaflet-extras/leaflet-providers",
|
||||
"description": "An extension to Leaflet that contains configurations for various free tile providers.",
|
||||
"main": "leaflet-providers.js",
|
||||
"keywords": [
|
||||
"leaflet",
|
||||
"stamen",
|
||||
"osm"
|
||||
],
|
||||
"license": "BSD-2-Clause",
|
||||
"ignore": [
|
||||
"**/.*",
|
||||
"node_modules",
|
||||
"bower_components",
|
||||
"test",
|
||||
"tests",
|
||||
"preview",
|
||||
"*.html"
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,127 @@
|
||||
/* Left will inherit from right (so we don't need to duplicate code */
|
||||
.github-fork-ribbon {
|
||||
/* The right and left lasses determine the side we attach our banner to */
|
||||
position: absolute;
|
||||
|
||||
/* Add a bit of padding to give some substance outside the "stitching" */
|
||||
padding: 2px 0;
|
||||
|
||||
/* Set the base colour */
|
||||
background-color: #a00;
|
||||
|
||||
/* Set a gradient: transparent black at the top to almost-transparent black at the bottom */
|
||||
background-image: -webkit-gradient(linear, left top, left bottom, from(rgba(0, 0, 0, 0.00)), to(rgba(0, 0, 0, 0.15)));
|
||||
background-image: -webkit-linear-gradient(top, rgba(0, 0, 0, 0.00), rgba(0, 0, 0, 0.15));
|
||||
background-image: -moz-linear-gradient(top, rgba(0, 0, 0, 0.00), rgba(0, 0, 0, 0.15));
|
||||
background-image: -o-linear-gradient(top, rgba(0, 0, 0, 0.00), rgba(0, 0, 0, 0.15));
|
||||
background-image: -ms-linear-gradient(top, rgba(0, 0, 0, 0.00), rgba(0, 0, 0, 0.15));
|
||||
background-image: linear-gradient(top, rgba(0, 0, 0, 0.00), rgba(0, 0, 0, 0.15));
|
||||
filter: progid:DXImageTransform.Microsoft.gradient(GradientType=0,StartColorStr='#000000', EndColorStr='#000000');
|
||||
|
||||
/* Add a drop shadow */
|
||||
-webkit-box-shadow: 0px 2px 3px 0px rgba(0, 0, 0, 0.5);
|
||||
box-shadow: 0px 2px 3px 0px rgba(0, 0, 0, 0.5);
|
||||
|
||||
z-index: 9999;
|
||||
}
|
||||
|
||||
.github-fork-ribbon a {
|
||||
/* Set the font */
|
||||
font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
|
||||
font-size: 13px;
|
||||
font-weight: 700;
|
||||
color: white;
|
||||
|
||||
/* Set the text properties */
|
||||
text-decoration: none;
|
||||
text-shadow: 0 -1px rgba(0,0,0,0.5);
|
||||
text-align: center;
|
||||
|
||||
/* Set the geometry. If you fiddle with these you'll also need to tweak the top and right values in #github-fork-ribbon. */
|
||||
width: 200px;
|
||||
line-height: 20px;
|
||||
|
||||
/* Set the layout properties */
|
||||
display: inline-block;
|
||||
padding: 2px 0;
|
||||
|
||||
/* Add "stitching" effect */
|
||||
border-width: 1px 0;
|
||||
border-style: dotted;
|
||||
border-color: rgba(255,255,255,0.7);
|
||||
}
|
||||
|
||||
.github-fork-ribbon-wrapper {
|
||||
width: 150px;
|
||||
height: 150px;
|
||||
position: absolute;
|
||||
overflow: hidden;
|
||||
top: 0;
|
||||
}
|
||||
|
||||
.github-fork-ribbon-wrapper.left {
|
||||
left: 0;
|
||||
}
|
||||
|
||||
.github-fork-ribbon-wrapper.right {
|
||||
right: 0;
|
||||
}
|
||||
|
||||
.github-fork-ribbon-wrapper.left-bottom {
|
||||
position: fixed;
|
||||
top: inherit;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
}
|
||||
|
||||
.github-fork-ribbon-wrapper.right-bottom {
|
||||
position: fixed;
|
||||
top: inherit;
|
||||
bottom: 0;
|
||||
right: 0;
|
||||
}
|
||||
|
||||
.github-fork-ribbon-wrapper.right .github-fork-ribbon {
|
||||
top: 42px;
|
||||
right: -43px;
|
||||
|
||||
/* Rotate the banner 45 degrees */
|
||||
-webkit-transform: rotate(45deg);
|
||||
-moz-transform: rotate(45deg);
|
||||
-o-transform: rotate(45deg);
|
||||
transform: rotate(45deg);
|
||||
}
|
||||
|
||||
.github-fork-ribbon-wrapper.left .github-fork-ribbon {
|
||||
top: 42px;
|
||||
left: -43px;
|
||||
|
||||
/* Rotate the banner -45 degrees */
|
||||
-webkit-transform: rotate(-45deg);
|
||||
-moz-transform: rotate(-45deg);
|
||||
-o-transform: rotate(-45deg);
|
||||
transform: rotate(-45deg);
|
||||
}
|
||||
|
||||
|
||||
.github-fork-ribbon-wrapper.left-bottom .github-fork-ribbon {
|
||||
top: 80px;
|
||||
left: -43px;
|
||||
|
||||
/* Rotate the banner -45 degrees */
|
||||
-webkit-transform: rotate(45deg);
|
||||
-moz-transform: rotate(45deg);
|
||||
-o-transform: rotate(45deg);
|
||||
transform: rotate(45deg);
|
||||
}
|
||||
|
||||
.github-fork-ribbon-wrapper.right-bottom .github-fork-ribbon {
|
||||
top: 80px;
|
||||
right: -43px;
|
||||
|
||||
/* Rotate the banner -45 degrees */
|
||||
-webkit-transform: rotate(-45deg);
|
||||
-moz-transform: rotate(-45deg);
|
||||
-o-transform: rotate(-45deg);
|
||||
transform: rotate(-45deg);
|
||||
}
|
||||
@@ -0,0 +1,68 @@
|
||||
/* IE voodoo courtesy of http://stackoverflow.com/a/4617511/263871 and
|
||||
* http://www.useragentman.com/IETransformsTranslator */
|
||||
.github-fork-ribbon-wrapper.right .github-fork-ribbon {
|
||||
/* IE positioning hack (couldn't find a transform-origin alternative for IE) */
|
||||
top: -22px;
|
||||
right: -62px;
|
||||
|
||||
/* IE8+ */
|
||||
-ms-filter: "progid:DXImageTransform.Microsoft.Matrix(M11=0.7071067811865474, M12=-0.7071067811865477, M21=0.7071067811865477, M22=0.7071067811865474, SizingMethod='auto expand')";
|
||||
/* IE6 and 7 */
|
||||
filter: progid:DXImageTransform.Microsoft.Matrix(
|
||||
M11=0.7071067811865474,
|
||||
M12=-0.7071067811865477,
|
||||
M21=0.7071067811865477,
|
||||
M22=0.7071067811865474,
|
||||
SizingMethod='auto expand'
|
||||
);
|
||||
}
|
||||
|
||||
.github-fork-ribbon-wrapper.left .github-fork-ribbon {
|
||||
top: -22px;
|
||||
left: -22px;
|
||||
|
||||
/* IE8+ */
|
||||
-ms-filter: "progid:DXImageTransform.Microsoft.Matrix(M11=0.7071067811865483, M12=0.7071067811865467, M21=-0.7071067811865467, M22=0.7071067811865483, SizingMethod='auto expand')";
|
||||
/* IE6 and 7 */
|
||||
filter: progid:DXImageTransform.Microsoft.Matrix(
|
||||
M11=0.7071067811865483,
|
||||
M12=0.7071067811865467,
|
||||
M21=-0.7071067811865467,
|
||||
M22=0.7071067811865483,
|
||||
SizingMethod='auto expand'
|
||||
);
|
||||
}
|
||||
|
||||
.github-fork-ribbon-wrapper.left-bottom .github-fork-ribbon {
|
||||
/* IE positioning hack (couldn't find a transform-origin alternative for IE) */
|
||||
top: 12px;
|
||||
left: -22px;
|
||||
|
||||
|
||||
/* IE8+ */
|
||||
-ms-filter: "progid:DXImageTransform.Microsoft.Matrix(M11=0.7071067811865474, M12=-0.7071067811865477, M21=0.7071067811865477, M22=0.7071067811865474, SizingMethod='auto expand')";
|
||||
/* IE6 and 7 */
|
||||
/* filter: progid:DXImageTransform.Microsoft.Matrix(
|
||||
M11=0.7071067811865474,
|
||||
M12=-0.7071067811865477,
|
||||
M21=0.7071067811865477,
|
||||
M22=0.7071067811865474,
|
||||
SizingMethod='auto expand'
|
||||
);
|
||||
*/}
|
||||
|
||||
.github-fork-ribbon-wrapper.right-bottom .github-fork-ribbon {
|
||||
top: 12px;
|
||||
right: -62px;
|
||||
|
||||
/* IE8+ */
|
||||
-ms-filter: "progid:DXImageTransform.Microsoft.Matrix(M11=0.7071067811865483, M12=0.7071067811865467, M21=-0.7071067811865467, M22=0.7071067811865483, SizingMethod='auto expand')";
|
||||
/* IE6 and 7 */
|
||||
filter: progid:DXImageTransform.Microsoft.Matrix(
|
||||
M11=0.7071067811865483,
|
||||
M12=0.7071067811865467,
|
||||
M21=-0.7071067811865467,
|
||||
M22=0.7071067811865483,
|
||||
SizingMethod='auto expand'
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,153 @@
|
||||
<!doctype html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<title>Leaflet Provider Demo</title>
|
||||
<meta charset="utf-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
|
||||
<!-- Leaflet style. REQUIRED! -->
|
||||
<link rel="stylesheet" href="http://cdn.leafletjs.com/leaflet-0.7/leaflet.css" />
|
||||
<style>
|
||||
html { height: 100% }
|
||||
body { height: 100%; margin: 0; padding: 0;}
|
||||
.map { height: 100% }
|
||||
</style>
|
||||
<!--Fork Me on Github ribbon, we're using the awsome version from simonwhitaker available at https://github.com/simonwhitaker/github-fork-ribbon-css -->
|
||||
<link rel="stylesheet" href="css/gh-fork-ribbon.css" />
|
||||
<!--[if IE]>
|
||||
<link rel="stylesheet" href="css/gh-fork-ribbon.ie.css" />
|
||||
<![endif]-->
|
||||
</head>
|
||||
<body>
|
||||
<div class="github-fork-ribbon-wrapper left">
|
||||
<div class="github-fork-ribbon">
|
||||
<a href="https://github.com/leaflet-extras/leaflet-providers">Fork me on GitHub</a>
|
||||
</div>
|
||||
</div>
|
||||
<div id="map" class="map"></div>
|
||||
|
||||
<script src="http://cdn.leafletjs.com/leaflet-0.7/leaflet-src.js"></script>
|
||||
<script src="leaflet-providers.js"></script>
|
||||
<script>
|
||||
var map = L.map('map', {
|
||||
center: [48, -3],
|
||||
zoom: 5,
|
||||
zoomControl: false
|
||||
});
|
||||
|
||||
var defaultLayer = L.tileLayer.provider('OpenStreetMap.Mapnik').addTo(map);
|
||||
|
||||
var baseLayers = {
|
||||
'OpenStreetMap Default': defaultLayer,
|
||||
'OpenStreetMap German Style': L.tileLayer.provider('OpenStreetMap.DE'),
|
||||
'OpenStreetMap Black and White': L.tileLayer.provider('OpenStreetMap.BlackAndWhite'),
|
||||
'OpenStreetMap H.O.T.': L.tileLayer.provider('OpenStreetMap.HOT'),
|
||||
'Thunderforest OpenCycleMap': L.tileLayer.provider('Thunderforest.OpenCycleMap'),
|
||||
'Thunderforest Transport': L.tileLayer.provider('Thunderforest.Transport'),
|
||||
'Thunderforest Landscape': L.tileLayer.provider('Thunderforest.Landscape'),
|
||||
'MapQuest OSM': L.tileLayer.provider('MapQuestOpen.OSM'),
|
||||
'MapQuest Aerial': L.tileLayer.provider('MapQuestOpen.Aerial'),
|
||||
'MapBox Example': L.tileLayer.provider('MapBox.examples.map-zr0njcqy'),
|
||||
'Stamen Toner': L.tileLayer.provider('Stamen.Toner'),
|
||||
'Stamen Terrain': L.tileLayer.provider('Stamen.Terrain'),
|
||||
'Stamen Watercolor': L.tileLayer.provider('Stamen.Watercolor'),
|
||||
'Esri WorldStreetMap': L.tileLayer.provider('Esri.WorldStreetMap'),
|
||||
'Esri DeLorme': L.tileLayer.provider('Esri.DeLorme'),
|
||||
'Esri WorldTopoMap': L.tileLayer.provider('Esri.WorldTopoMap'),
|
||||
'Esri WorldImagery': L.tileLayer.provider('Esri.WorldImagery'),
|
||||
'Esri WorldTerrain': L.tileLayer.provider('Esri.WorldTerrain'),
|
||||
'Esri WorldShadedRelief': L.tileLayer.provider('Esri.WorldShadedRelief'),
|
||||
'Esri WorldPhysical': L.tileLayer.provider('Esri.WorldPhysical'),
|
||||
'Esri OceanBasemap': L.tileLayer.provider('Esri.OceanBasemap'),
|
||||
'Esri NatGeoWorldMap': L.tileLayer.provider('Esri.NatGeoWorldMap'),
|
||||
'Esri WorldGrayCanvas': L.tileLayer.provider('Esri.WorldGrayCanvas'),
|
||||
'Nokia Normal Day': L.tileLayer.provider('Nokia.normalDay'),
|
||||
'Nokia Normal Day Grey': L.tileLayer.provider('Nokia.normalGreyDay'),
|
||||
'Nokia Satellite': L.tileLayer.provider('Nokia.satelliteNoLabelsDay'),
|
||||
'Nokia Satellite (Labeled)': L.tileLayer.provider('Nokia.satelliteYesLabelsDay'),
|
||||
'Nokia Terrain': L.tileLayer.provider('Nokia.terrainDay'),
|
||||
'Acetate': L.tileLayer.provider('Acetate')
|
||||
};
|
||||
|
||||
var overlayLayers = {
|
||||
'OpenSeaMap': L.tileLayer.provider('OpenSeaMap'),
|
||||
'OpenWeatherMap Clouds': L.tileLayer.provider('OpenWeatherMap.Clouds'),
|
||||
'OpenWeatherMap CloudsClassic': L.tileLayer.provider('OpenWeatherMap.CloudsClassic'),
|
||||
'OpenWeatherMap Precipitation': L.tileLayer.provider('OpenWeatherMap.Precipitation'),
|
||||
'OpenWeatherMap PrecipitationClassic': L.tileLayer.provider('OpenWeatherMap.PrecipitationClassic'),
|
||||
'OpenWeatherMap Rain': L.tileLayer.provider('OpenWeatherMap.Rain'),
|
||||
'OpenWeatherMap RainClassic': L.tileLayer.provider('OpenWeatherMap.RainClassic'),
|
||||
'OpenWeatherMap Pressure': L.tileLayer.provider('OpenWeatherMap.Pressure'),
|
||||
'OpenWeatherMap PressureContour': L.tileLayer.provider('OpenWeatherMap.PressureContour'),
|
||||
'OpenWeatherMap Wind': L.tileLayer.provider('OpenWeatherMap.Wind'),
|
||||
'OpenWeatherMap Temperature': L.tileLayer.provider('OpenWeatherMap.Temperature'),
|
||||
'OpenWeatherMap Snow': L.tileLayer.provider('OpenWeatherMap.Snow')
|
||||
};
|
||||
|
||||
var layerControl = L.control.layers(baseLayers, overlayLayers, {collapsed: false}).addTo(map);
|
||||
|
||||
/* you could also use the following code instead
|
||||
var map = new L.Map('map').setView([48, -3],5);
|
||||
|
||||
var defaultLayer = L.tileLayer.provider('OpenStreetMap.Mapnik').addTo(map);
|
||||
|
||||
var baseLayers = [
|
||||
'OpenStreetMap.Mapnik',
|
||||
'OpenStreetMap.DE',
|
||||
'OpenStreetMap.BlackAndWhite',
|
||||
'Thunderforest.OpenCycleMap',
|
||||
'Thunderforest.Transport',
|
||||
'Thunderforest.Landscape',
|
||||
'MapQuestOpen.OSM',
|
||||
'MapQuestOpen.Aerial',
|
||||
'MapBox.examples.map-zr0njcqy',
|
||||
'Stamen.Toner',
|
||||
'Stamen.Terrain',
|
||||
'Stamen.Watercolor',
|
||||
'Esri.WorldStreetMap',
|
||||
'Esri.DeLorme',
|
||||
'Esri.WorldTopoMap',
|
||||
'Esri.WorldImagery',
|
||||
'Esri.WorldTerrain',
|
||||
'Esri.WorldShadedRelief',
|
||||
'Esri.WorldPhysical',
|
||||
'Esri.OceanBasemap',
|
||||
'Esri.NatGeoWorldMap',
|
||||
'Esri.WorldGrayCanvas',
|
||||
'Nokia.normalDay',
|
||||
'Nokia.normalGreyDay',
|
||||
'Nokia.satelliteNoLabelsDay',
|
||||
'Nokia.satelliteYesLabelsDay,
|
||||
'Nokia.terrainDay'
|
||||
];
|
||||
|
||||
var overlayLayers = [
|
||||
'OpenWeatherMap.Clouds',
|
||||
'OpenWeatherMap.CloudsClassic',
|
||||
'OpenWeatherMap.Precipitation',
|
||||
'OpenWeatherMap.PrecipitationClassic',
|
||||
'OpenWeatherMap.Rain',
|
||||
'OpenWeatherMap.RainClassic',
|
||||
'OpenWeatherMap.Pressure',
|
||||
'OpenWeatherMap.PressureContour',
|
||||
'OpenWeatherMap.Wind',
|
||||
'OpenWeatherMap.Temperature',
|
||||
'OpenWeatherMap.Snow'
|
||||
];
|
||||
|
||||
L.control.layers.provided(baseLayers, overlayLayers, {collapsed: false}).addTo(map);
|
||||
*/
|
||||
|
||||
// resize layers control to fit into view.
|
||||
function resizeLayerControl() {
|
||||
var layerControlHeight = document.body.clientHeight - (10 + 50);
|
||||
var layerControl = document.getElementsByClassName('leaflet-control-layers-expanded')[0];
|
||||
|
||||
layerControl.style.overflowY = 'auto';
|
||||
layerControl.style.maxHeight = layerControlHeight + 'px';
|
||||
}
|
||||
map.on('resize', resizeLayerControl);
|
||||
resizeLayerControl();
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,458 @@
|
||||
(function () {
|
||||
'use strict';
|
||||
|
||||
L.TileLayer.Provider = L.TileLayer.extend({
|
||||
initialize: function (arg, options) {
|
||||
var providers = L.TileLayer.Provider.providers;
|
||||
|
||||
var parts = arg.split('.');
|
||||
|
||||
var providerName = parts[0];
|
||||
var variantName = parts[1];
|
||||
|
||||
if (!providers[providerName]) {
|
||||
throw 'No such provider (' + providerName + ')';
|
||||
}
|
||||
|
||||
var provider = {
|
||||
url: providers[providerName].url,
|
||||
options: providers[providerName].options
|
||||
};
|
||||
|
||||
// overwrite values in provider from variant.
|
||||
if (variantName && 'variants' in providers[providerName]) {
|
||||
if (!(variantName in providers[providerName].variants)) {
|
||||
throw 'No such name in provider (' + variantName + ')';
|
||||
}
|
||||
var variant = providers[providerName].variants[variantName];
|
||||
provider = {
|
||||
url: variant.url || provider.url,
|
||||
options: L.Util.extend({}, provider.options, variant.options)
|
||||
};
|
||||
} else if (typeof provider.url === 'function') {
|
||||
provider.url = provider.url(parts.splice(1, parts.length - 1).join('.'));
|
||||
}
|
||||
|
||||
// replace attribution placeholders with their values from toplevel provider attribution,
|
||||
// recursively
|
||||
var attributionReplacer = function (attr) {
|
||||
if (attr.indexOf('{attribution.') === -1) {
|
||||
return attr;
|
||||
}
|
||||
return attr.replace(/\{attribution.(\w*)\}/,
|
||||
function (match, attributionName) {
|
||||
return attributionReplacer(providers[attributionName].options.attribution);
|
||||
}
|
||||
);
|
||||
};
|
||||
provider.options.attribution = attributionReplacer(provider.options.attribution);
|
||||
|
||||
// Compute final options combining provider options with any user overrides
|
||||
var layerOpts = L.Util.extend({}, provider.options, options);
|
||||
L.TileLayer.prototype.initialize.call(this, provider.url, layerOpts);
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* Definition of providers.
|
||||
* see http://leafletjs.com/reference.html#tilelayer for options in the options map.
|
||||
*/
|
||||
|
||||
//jshint maxlen:220
|
||||
L.TileLayer.Provider.providers = {
|
||||
OpenStreetMap: {
|
||||
url: 'http://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png',
|
||||
options: {
|
||||
attribution:
|
||||
'© <a href="http://openstreetmap.org">OpenStreetMap</a> contributors, ' +
|
||||
'<a href="http://creativecommons.org/licenses/by-sa/2.0/">CC-BY-SA</a>'
|
||||
},
|
||||
variants: {
|
||||
Mapnik: {},
|
||||
BlackAndWhite: {
|
||||
url: 'http://{s}.www.toolserver.org/tiles/bw-mapnik/{z}/{x}/{y}.png'
|
||||
},
|
||||
DE: {
|
||||
url: 'http://{s}.tile.openstreetmap.de/tiles/osmde/{z}/{x}/{y}.png'
|
||||
},
|
||||
HOT: {
|
||||
url: 'http://{s}.tile.openstreetmap.fr/hot/{z}/{x}/{y}.png',
|
||||
options: {
|
||||
attribution: '{attribution.OpenStreetMap}, Tiles courtesy of <a href="http://hot.openstreetmap.org/" target="_blank">Humanitarian OpenStreetMap Team</a>'
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
OpenCycleMap: {
|
||||
url: 'http://{s}.tile.opencyclemap.org/cycle/{z}/{x}/{y}.png',
|
||||
options: {
|
||||
attribution:
|
||||
'© <a href="http://www.opencyclemap.org">OpenCycleMap</a>, {attribution.OpenStreetMap}'
|
||||
}
|
||||
},
|
||||
OpenSeaMap: {
|
||||
url: 'http://tiles.openseamap.org/seamark/{z}/{x}/{y}.png',
|
||||
options: {
|
||||
attribution: 'Map data: © <a href="http://www.openseamap.org">OpenSeaMap</a> contributors'
|
||||
}
|
||||
},
|
||||
Thunderforest: {
|
||||
url: 'http://{s}.tile.opencyclemap.org/cycle/{z}/{x}/{y}.png',
|
||||
options: {
|
||||
attribution: '{attribution.OpenCycleMap}'
|
||||
},
|
||||
variants: {
|
||||
OpenCycleMap: {},
|
||||
Transport: {
|
||||
url: 'http://{s}.tile2.opencyclemap.org/transport/{z}/{x}/{y}.png'
|
||||
},
|
||||
Landscape: {
|
||||
url: 'http://{s}.tile3.opencyclemap.org/landscape/{z}/{x}/{y}.png'
|
||||
},
|
||||
Outdoors: {
|
||||
url: 'http://{s}.tile.thunderforest.com/outdoors/{z}/{x}/{y}.png'
|
||||
}
|
||||
}
|
||||
},
|
||||
OpenMapSurfer: {
|
||||
url: 'http://openmapsurfer.uni-hd.de/tiles/roads/x={x}&y={y}&z={z}',
|
||||
options: {
|
||||
attribution: 'Imagery from <a href="http://giscience.uni-hd.de/">GIScience Research Group @ University of Heidelberg</a> — Map data {attribution.OpenStreetMap}'
|
||||
},
|
||||
variants: {
|
||||
Roads: {},
|
||||
AdminBounds: {
|
||||
url: 'http://openmapsurfer.uni-hd.de/tiles/adminb/x={x}&y={y}&z={z}'
|
||||
},
|
||||
Grayscale: {
|
||||
url: 'http://openmapsurfer.uni-hd.de/tiles/roadsg/x={x}&y={y}&z={z}'
|
||||
}
|
||||
}
|
||||
},
|
||||
MapQuestOpen: {
|
||||
url: 'http://otile{s}.mqcdn.com/tiles/1.0.0/map/{z}/{x}/{y}.jpeg',
|
||||
options: {
|
||||
attribution:
|
||||
'Tiles Courtesy of <a href="http://www.mapquest.com/">MapQuest</a> — ' +
|
||||
'Map data {attribution.OpenStreetMap}',
|
||||
subdomains: '1234'
|
||||
},
|
||||
variants: {
|
||||
OSM: {},
|
||||
Aerial: {
|
||||
url: 'http://oatile{s}.mqcdn.com/tiles/1.0.0/sat/{z}/{x}/{y}.jpg',
|
||||
options: {
|
||||
attribution:
|
||||
'Tiles Courtesy of <a href="http://www.mapquest.com/">MapQuest</a> — ' +
|
||||
'Portions Courtesy NASA/JPL-Caltech and U.S. Depart. of Agriculture, Farm Service Agency'
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
MapBox: {
|
||||
url: function (id) {
|
||||
return 'http://{s}.tiles.mapbox.com/v3/' + id + '/{z}/{x}/{y}.png';
|
||||
},
|
||||
options: {
|
||||
attribution:
|
||||
'Imagery from <a href="http://mapbox.com/about/maps/">MapBox</a> — ' +
|
||||
'Map data {attribution.OpenStreetMap}',
|
||||
subdomains: 'abcd'
|
||||
}
|
||||
},
|
||||
Stamen: {
|
||||
url: 'http://{s}.tile.stamen.com/toner/{z}/{x}/{y}.png',
|
||||
options: {
|
||||
attribution:
|
||||
'Map tiles by <a href="http://stamen.com">Stamen Design</a>, ' +
|
||||
'<a href="http://creativecommons.org/licenses/by/3.0">CC BY 3.0</a> — ' +
|
||||
'Map data {attribution.OpenStreetMap}',
|
||||
subdomains: 'abcd',
|
||||
minZoom: 0,
|
||||
maxZoom: 20
|
||||
},
|
||||
variants: {
|
||||
Toner: {},
|
||||
TonerBackground: {
|
||||
url: 'http://{s}.tile.stamen.com/toner-background/{z}/{x}/{y}.png'
|
||||
},
|
||||
TonerHybrid: {
|
||||
url: 'http://{s}.tile.stamen.com/toner-hybrid/{z}/{x}/{y}.png'
|
||||
},
|
||||
TonerLines: {
|
||||
url: 'http://{s}.tile.stamen.com/toner-lines/{z}/{x}/{y}.png'
|
||||
},
|
||||
TonerLabels: {
|
||||
url: 'http://{s}.tile.stamen.com/toner-labels/{z}/{x}/{y}.png'
|
||||
},
|
||||
TonerLite: {
|
||||
url: 'http://{s}.tile.stamen.com/toner-lite/{z}/{x}/{y}.png'
|
||||
},
|
||||
Terrain: {
|
||||
url: 'http://{s}.tile.stamen.com/terrain/{z}/{x}/{y}.jpg',
|
||||
options: {
|
||||
minZoom: 4,
|
||||
maxZoom: 18
|
||||
}
|
||||
},
|
||||
TerrainBackground: {
|
||||
url: 'http://{s}.tile.stamen.com/terrain-background/{z}/{x}/{y}.jpg',
|
||||
options: {
|
||||
minZoom: 4,
|
||||
maxZoom: 18
|
||||
}
|
||||
},
|
||||
Watercolor: {
|
||||
url: 'http://{s}.tile.stamen.com/watercolor/{z}/{x}/{y}.jpg',
|
||||
options: {
|
||||
minZoom: 3,
|
||||
maxZoom: 16
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
Esri: {
|
||||
url: 'http://server.arcgisonline.com/ArcGIS/rest/services/World_Street_Map/MapServer/tile/{z}/{y}/{x}',
|
||||
options: {
|
||||
attribution: 'Tiles © Esri'
|
||||
},
|
||||
variants: {
|
||||
WorldStreetMap: {
|
||||
options: {
|
||||
attribution:
|
||||
'{attribution.Esri} — ' +
|
||||
'Source: Esri, DeLorme, NAVTEQ, USGS, Intermap, iPC, NRCAN, Esri Japan, METI, Esri China (Hong Kong), Esri (Thailand), TomTom, 2012'
|
||||
}
|
||||
},
|
||||
DeLorme: {
|
||||
url: 'http://server.arcgisonline.com/ArcGIS/rest/services/Specialty/DeLorme_World_Base_Map/MapServer/tile/{z}/{y}/{x}',
|
||||
options: {
|
||||
minZoom: 1,
|
||||
maxZoom: 11,
|
||||
attribution: '{attribution.Esri} — Copyright: ©2012 DeLorme'
|
||||
}
|
||||
},
|
||||
WorldTopoMap: {
|
||||
url: 'http://server.arcgisonline.com/ArcGIS/rest/services/World_Topo_Map/MapServer/tile/{z}/{y}/{x}',
|
||||
options: {
|
||||
attribution:
|
||||
'{attribution.Esri} — ' +
|
||||
'Esri, DeLorme, NAVTEQ, TomTom, Intermap, iPC, USGS, FAO, NPS, NRCAN, GeoBase, Kadaster NL, Ordnance Survey, Esri Japan, METI, Esri China (Hong Kong), and the GIS User Community'
|
||||
}
|
||||
},
|
||||
WorldImagery: {
|
||||
url: 'http://server.arcgisonline.com/ArcGIS/rest/services/World_Imagery/MapServer/tile/{z}/{y}/{x}',
|
||||
options: {
|
||||
attribution:
|
||||
'{attribution.Esri} — ' +
|
||||
'Source: Esri, i-cubed, USDA, USGS, AEX, GeoEye, Getmapping, Aerogrid, IGN, IGP, UPR-EGP, and the GIS User Community'
|
||||
}
|
||||
},
|
||||
WorldTerrain: {
|
||||
url: 'http://server.arcgisonline.com/ArcGIS/rest/services/World_Terrain_Base/MapServer/tile/{z}/{y}/{x}',
|
||||
options: {
|
||||
maxZoom: 13,
|
||||
attribution:
|
||||
'{attribution.Esri} — ' +
|
||||
'Source: USGS, Esri, TANA, DeLorme, and NPS'
|
||||
}
|
||||
},
|
||||
WorldShadedRelief: {
|
||||
url: 'http://server.arcgisonline.com/ArcGIS/rest/services/World_Shaded_Relief/MapServer/tile/{z}/{y}/{x}',
|
||||
options: {
|
||||
maxZoom: 13,
|
||||
attribution: '{attribution.Esri} — Source: Esri'
|
||||
}
|
||||
},
|
||||
WorldPhysical: {
|
||||
url: 'http://server.arcgisonline.com/ArcGIS/rest/services/World_Physical_Map/MapServer/tile/{z}/{y}/{x}',
|
||||
options: {
|
||||
maxZoom: 8,
|
||||
attribution: '{attribution.Esri} — Source: US National Park Service'
|
||||
}
|
||||
},
|
||||
OceanBasemap: {
|
||||
url: 'http://services.arcgisonline.com/ArcGIS/rest/services/Ocean_Basemap/MapServer/tile/{z}/{y}/{x}',
|
||||
options: {
|
||||
maxZoom: 13,
|
||||
attribution: '{attribution.Esri} — Sources: GEBCO, NOAA, CHS, OSU, UNH, CSUMB, National Geographic, DeLorme, NAVTEQ, and Esri'
|
||||
}
|
||||
},
|
||||
NatGeoWorldMap: {
|
||||
url: 'http://services.arcgisonline.com/ArcGIS/rest/services/NatGeo_World_Map/MapServer/tile/{z}/{y}/{x}',
|
||||
options: {
|
||||
maxZoom: 16,
|
||||
attribution: '{attribution.Esri} — National Geographic, Esri, DeLorme, NAVTEQ, UNEP-WCMC, USGS, NASA, ESA, METI, NRCAN, GEBCO, NOAA, iPC'
|
||||
}
|
||||
},
|
||||
WorldGrayCanvas: {
|
||||
url: 'http://server.arcgisonline.com/ArcGIS/rest/services/Canvas/World_Light_Gray_Base/MapServer/tile/{z}/{y}/{x}',
|
||||
options: {
|
||||
maxZoom: 16,
|
||||
attribution: '{attribution.Esri} — Esri, DeLorme, NAVTEQ'
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
OpenWeatherMap: {
|
||||
options: {
|
||||
attribution: 'Map data © <a href="http://openweathermap.org">OpenWeatherMap</a>',
|
||||
opacity: 0.5
|
||||
},
|
||||
variants: {
|
||||
Clouds: {
|
||||
url: 'http://{s}.tile.openweathermap.org/map/clouds/{z}/{x}/{y}.png'
|
||||
},
|
||||
CloudsClassic: {
|
||||
url: 'http://{s}.tile.openweathermap.org/map/clouds_cls/{z}/{x}/{y}.png'
|
||||
},
|
||||
Precipitation: {
|
||||
url: 'http://{s}.tile.openweathermap.org/map/precipitation/{z}/{x}/{y}.png'
|
||||
},
|
||||
PrecipitationClassic: {
|
||||
url: 'http://{s}.tile.openweathermap.org/map/precipitation_cls/{z}/{x}/{y}.png'
|
||||
},
|
||||
Rain: {
|
||||
url: 'http://{s}.tile.openweathermap.org/map/rain/{z}/{x}/{y}.png'
|
||||
},
|
||||
RainClassic: {
|
||||
url: 'http://{s}.tile.openweathermap.org/map/rain_cls/{z}/{x}/{y}.png'
|
||||
},
|
||||
Pressure: {
|
||||
url: 'http://{s}.tile.openweathermap.org/map/pressure/{z}/{x}/{y}.png'
|
||||
},
|
||||
PressureContour: {
|
||||
url: 'http://{s}.tile.openweathermap.org/map/pressure_cntr/{z}/{x}/{y}.png'
|
||||
},
|
||||
Wind: {
|
||||
url: 'http://{s}.tile.openweathermap.org/map/wind/{z}/{x}/{y}.png'
|
||||
},
|
||||
Temperature: {
|
||||
url: 'http://{s}.tile.openweathermap.org/map/temp/{z}/{x}/{y}.png'
|
||||
},
|
||||
Snow: {
|
||||
url: 'http://{s}.tile.openweathermap.org/map/snow/{z}/{x}/{y}.png'
|
||||
}
|
||||
}
|
||||
},
|
||||
Nokia: {
|
||||
options: {
|
||||
attribution:
|
||||
'Map © <a href="http://developer.here.com">Nokia</a>, Data © NAVTEQ 2012',
|
||||
subdomains: '1234',
|
||||
devID: 'xyz', //These basemaps are free and you can sign up here: http://developer.here.com/plans
|
||||
appID: 'abc'
|
||||
},
|
||||
variants: {
|
||||
normalDay: {
|
||||
url: 'http://{s}.maptile.lbs.ovi.com/maptiler/v2/maptile/newest/normal.day/{z}/{x}/{y}/256/png8?token={devID}&app_id={appID}'
|
||||
},
|
||||
normalGreyDay: {
|
||||
url: 'http://{s}.maptile.lbs.ovi.com/maptiler/v2/maptile/newest/normal.day.grey/{z}/{x}/{y}/256/png8?token={devID}&app_id={appID}'
|
||||
},
|
||||
satelliteNoLabelsDay: {
|
||||
url: 'http://{s}.maptile.lbs.ovi.com/maptiler/v2/maptile/newest/satellite.day/{z}/{x}/{y}/256/png8?token={devID}&app_id={appID}'
|
||||
},
|
||||
satelliteYesLabelsDay: {
|
||||
url: 'http://{s}.maptile.lbs.ovi.com/maptiler/v2/maptile/newest/hybrid.day/{z}/{x}/{y}/256/png8?token={devID}&app_id={appID}'
|
||||
},
|
||||
terrainDay: {
|
||||
url: 'http://{s}.maptile.lbs.ovi.com/maptiler/v2/maptile/newest/terrain.day/{z}/{x}/{y}/256/png8?token={devID}&app_id={appID}'
|
||||
}
|
||||
}
|
||||
},
|
||||
Acetate: {
|
||||
url: 'http://a{s}.acetate.geoiq.com/tiles/acetate-hillshading/{z}/{x}/{y}.png',
|
||||
options: {
|
||||
attribution:
|
||||
'©2012 Esri & Stamen, Data from OSM and Natural Earth',
|
||||
subdomains: '0123',
|
||||
minZoom: 2,
|
||||
maxZoom: 18
|
||||
},
|
||||
variants: {
|
||||
all: {},
|
||||
basemap: {
|
||||
url: 'http://a{s}.acetate.geoiq.com/tiles/acetate-base/{z}/{x}/{y}.png'
|
||||
},
|
||||
terrain: {
|
||||
url: 'http://a{s}.acetate.geoiq.com/tiles/terrain/{z}/{x}/{y}.png'
|
||||
},
|
||||
foreground: {
|
||||
url: 'http://a{s}.acetate.geoiq.com/tiles/acetate-fg/{z}/{x}/{y}.png'
|
||||
},
|
||||
roads: {
|
||||
url: 'http://a{s}.acetate.geoiq.com/tiles/acetate-roads/{z}/{x}/{y}.png'
|
||||
},
|
||||
labels: {
|
||||
url: 'http://a{s}.acetate.geoiq.com/tiles/acetate-labels/{z}/{x}/{y}.png'
|
||||
},
|
||||
hillshading: {
|
||||
url: 'http://a{s}.acetate.geoiq.com/tiles/hillshading/{z}/{x}/{y}.png'
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
L.tileLayer.provider = function (provider, options) {
|
||||
return new L.TileLayer.Provider(provider, options);
|
||||
};
|
||||
|
||||
L.Control.Layers.Provided = L.Control.Layers.extend({
|
||||
initialize: function (base, overlay, options) {
|
||||
var first;
|
||||
|
||||
var labelFormatter = function (label) {
|
||||
return label.replace(/\./g, ': ').replace(/([a-z])([A-Z])/g, '$1 $2');
|
||||
};
|
||||
|
||||
if (base.length) {
|
||||
(function () {
|
||||
var out = {},
|
||||
len = base.length,
|
||||
i = 0;
|
||||
|
||||
while (i < len) {
|
||||
if (typeof base[i] === 'string') {
|
||||
if (i === 0) {
|
||||
first = L.tileLayer.provider(base[0]);
|
||||
out[labelFormatter(base[i])] = first;
|
||||
} else {
|
||||
out[labelFormatter(base[i])] = L.tileLayer.provider(base[i]);
|
||||
}
|
||||
}
|
||||
i++;
|
||||
}
|
||||
base = out;
|
||||
}());
|
||||
this._first = first;
|
||||
}
|
||||
|
||||
if (overlay && overlay.length) {
|
||||
(function () {
|
||||
var out = {},
|
||||
len = overlay.length,
|
||||
i = 0;
|
||||
|
||||
while (i < len) {
|
||||
if (typeof overlay[i] === 'string') {
|
||||
out[labelFormatter(overlay[i])] = L.tileLayer.provider(overlay[i]);
|
||||
}
|
||||
i++;
|
||||
}
|
||||
overlay = out;
|
||||
}());
|
||||
}
|
||||
L.Control.Layers.prototype.initialize.call(this, base, overlay, options);
|
||||
},
|
||||
onAdd: function (map) {
|
||||
this._first.addTo(map);
|
||||
return L.Control.Layers.prototype.onAdd.call(this, map);
|
||||
}
|
||||
});
|
||||
|
||||
L.control.layers.provided = function (baseLayers, overlays, options) {
|
||||
return new L.Control.Layers.Provided(baseLayers, overlays, options);
|
||||
};
|
||||
}());
|
||||
|
||||
@@ -0,0 +1,9 @@
|
||||
Copyright (c) 2013 Leaflet Providers contributors
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
|
||||
|
||||
_THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE._
|
||||
@@ -0,0 +1,20 @@
|
||||
{
|
||||
"name": "leaflet-providers",
|
||||
"version": "1.0.3",
|
||||
"description": "An extension to Leaflet that contains configurations for various free tile providers.",
|
||||
"main": "leaflet-providers.js",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git://github.com/leaflet-extras/leaflet-providers.git"
|
||||
},
|
||||
"scripts":{
|
||||
"pretest":"jshint leaflet-providers.js"
|
||||
},
|
||||
"license": "BSD-2-Clause",
|
||||
"bugs": {
|
||||
"url": "https://github.com/leaflet-extras/leaflet-providers/issues"
|
||||
},
|
||||
"devDependencies": {
|
||||
"jshint": "~2.1.11"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,210 @@
|
||||
/*
|
||||
* Leaflet.layerscontrol-minimap
|
||||
*
|
||||
* Layers control with synced minimaps for Leaflet.
|
||||
*
|
||||
* Jan Pieter Waagmeester <jieter@jieter.nl>
|
||||
*/
|
||||
(function () {
|
||||
'use strict';
|
||||
|
||||
var cloneLayer = function (layer) {
|
||||
var options = layer.options;
|
||||
if (layer instanceof L.TileLayer) {
|
||||
return L.tileLayer(layer._url, options);
|
||||
}
|
||||
if (layer instanceof L.ImageOverlay) {
|
||||
return L.imageOverlay(layer._url, layer._bounds, options);
|
||||
}
|
||||
|
||||
if (layer instanceof L.Polygon || layer instanceof L.Rectangle) {
|
||||
return L.polygon(layer.getLatLngs(), options);
|
||||
}
|
||||
if (layer instanceof L.Marker) {
|
||||
return L.marker(layer.getLatLng(), options);
|
||||
}
|
||||
if (layer instanceof L.circleMarker) {
|
||||
return L.circleMarker(layer.getLatLng(), options);
|
||||
}
|
||||
if (layer instanceof L.Polyline) {
|
||||
return L.polyline(layer.getLatLngs(), options);
|
||||
}
|
||||
if (layer instanceof L.MultiPolyline) {
|
||||
return L.polyline(layer.getLatLngs(), options);
|
||||
}
|
||||
if (layer instanceof L.MultiPolygon) {
|
||||
return L.MultiPolygon(layer.getLatLngs(), options);
|
||||
}
|
||||
if (layer instanceof L.Circle) {
|
||||
return L.circle(layer.getLatLng(), layer.getRadius(), options);
|
||||
}
|
||||
if (layer instanceof L.GeoJSON) {
|
||||
return L.geoJson(layer.toGeoJSON(), options);
|
||||
}
|
||||
|
||||
// no interaction on minimaps, add FeatureGroup as LayerGroup
|
||||
if (layer instanceof L.LayerGroup || layer instanceof L.FeatureGroup) {
|
||||
var layergroup = L.layerGroup();
|
||||
layer.eachLayer(function (inner) {
|
||||
layergroup.addLayer(cloneLayer(inner));
|
||||
});
|
||||
return layergroup;
|
||||
}
|
||||
};
|
||||
|
||||
L.Control.Layers.Minimap = L.Control.Layers.extend({
|
||||
options: {
|
||||
position: 'topright',
|
||||
topPadding: 10,
|
||||
bottomPadding: 40,
|
||||
overlayBackgroundLayer: L.tileLayer('http://a{s}.acetate.geoiq.com/tiles/acetate-base/{z}/{x}/{y}.png', {
|
||||
attribution: '©2012 Esri & Stamen, Data from OSM and Natural Earth',
|
||||
subdomains: '0123',
|
||||
minZoom: 2,
|
||||
maxZoom: 18
|
||||
})
|
||||
},
|
||||
|
||||
isCollapsed: function () {
|
||||
return !L.DomUtil.hasClass(this._container, 'leaflet-control-layers-expanded');
|
||||
},
|
||||
|
||||
_expand: function () {
|
||||
L.Control.Layers.prototype._expand.call(this);
|
||||
this._onListScroll();
|
||||
},
|
||||
|
||||
_initLayout: function () {
|
||||
L.Control.Layers.prototype._initLayout.call(this);
|
||||
|
||||
L.DomUtil.addClass(this._container, 'leaflet-control-layers-minimap');
|
||||
L.DomEvent.on(this._container, 'scroll', this._onListScroll, this);
|
||||
},
|
||||
|
||||
_update: function () {
|
||||
L.Control.Layers.prototype._update.call(this);
|
||||
|
||||
this._map.on('resize', this._onResize, this);
|
||||
this._onResize();
|
||||
|
||||
this._map.whenReady(this._onListScroll, this);
|
||||
},
|
||||
|
||||
_addItem: function (obj) {
|
||||
var container = obj.overlay ? this._overlaysList : this._baseLayersList;
|
||||
var label = L.DomUtil.create('label', 'leaflet-minimap-container', container);
|
||||
var checked = this._map.hasLayer(obj.layer);
|
||||
|
||||
this._createMinimap(
|
||||
L.DomUtil.create('div', 'leaflet-minimap', label),
|
||||
obj.layer,
|
||||
obj.overlay
|
||||
);
|
||||
var span = L.DomUtil.create('span', 'leaflet-minimap-label', label);
|
||||
|
||||
var input;
|
||||
if (obj.overlay) {
|
||||
input = document.createElement('input');
|
||||
input.type = 'checkbox';
|
||||
input.className = 'leaflet-control-layers-selector';
|
||||
input.defaultChecked = checked;
|
||||
} else {
|
||||
input = this._createRadioElement('leaflet-base-layers', checked);
|
||||
}
|
||||
input.layerId = L.stamp(obj.layer);
|
||||
span.appendChild(input);
|
||||
|
||||
L.DomEvent.on(label, 'click', this._onInputClick, this);
|
||||
|
||||
var name = L.DomUtil.create('span', '', span);
|
||||
name.innerHTML = ' ' + obj.name;
|
||||
|
||||
return label;
|
||||
},
|
||||
|
||||
_onResize: function () {
|
||||
var mapHeight = this._map.getContainer().clientHeight;
|
||||
var controlHeight = this._container.clientHeight;
|
||||
|
||||
if (controlHeight > mapHeight - this.options.bottomPadding) {
|
||||
this._container.style.overflowY = 'scroll';
|
||||
}
|
||||
this._container.style.maxHeight = (mapHeight - this.options.bottomPadding - this.options.topPadding) + 'px';
|
||||
},
|
||||
|
||||
_onListScroll: function () {
|
||||
var minimaps = document.getElementsByClassName('leaflet-minimap-container');
|
||||
if (minimaps.length === 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
var first, last;
|
||||
if (this.isCollapsed()) {
|
||||
first = last = -1;
|
||||
} else {
|
||||
var minimapHeight = minimaps.item(0).clientHeight;
|
||||
var container = this._container;
|
||||
var listHeight = container.clientHeight;
|
||||
var scrollTop = container.scrollTop;
|
||||
|
||||
first = Math.floor(scrollTop / minimapHeight);
|
||||
last = Math.ceil((scrollTop + listHeight) / minimapHeight);
|
||||
}
|
||||
|
||||
for (var i = 0; i < minimaps.length; ++i) {
|
||||
var minimap = minimaps[i].childNodes.item(0);
|
||||
var map = minimap._miniMap;
|
||||
var layer = map._layer;
|
||||
|
||||
if (!layer) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (i >= first && i <= last) {
|
||||
if (!map.hasLayer(layer)) {
|
||||
layer.addTo(map);
|
||||
}
|
||||
map.invalidateSize();
|
||||
} else {
|
||||
if (map.hasLayer(layer)) {
|
||||
map.removeLayer(layer);
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
_createMinimap: function (mapContainer, originalLayer, isOverlay) {
|
||||
var minimap = mapContainer._miniMap = L.map(mapContainer, {
|
||||
attributionControl: false,
|
||||
zoomControl: false
|
||||
});
|
||||
|
||||
// disable interaction.
|
||||
minimap.dragging.disable();
|
||||
minimap.touchZoom.disable();
|
||||
minimap.doubleClickZoom.disable();
|
||||
minimap.scrollWheelZoom.disable();
|
||||
|
||||
// create tilelayer, but do not add it to the map yet.
|
||||
if (isOverlay) {
|
||||
minimap._layer = L.layerGroup([
|
||||
cloneLayer(this.options.overlayBackgroundLayer),
|
||||
cloneLayer(originalLayer)
|
||||
]);
|
||||
} else {
|
||||
minimap._layer = cloneLayer(originalLayer);
|
||||
}
|
||||
|
||||
var map = this._map;
|
||||
map.whenReady(function () {
|
||||
minimap.setView(map.getCenter(), map.getZoom());
|
||||
map.sync(minimap);
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
L.control.layers.minimap = function (baseLayers, overlays, options) {
|
||||
return new L.Control.Layers.Minimap(baseLayers, overlays, options);
|
||||
};
|
||||
|
||||
})();
|
||||
@@ -0,0 +1,106 @@
|
||||
/*
|
||||
* Extends L.Map to synchronize the interaction on one map to one or more other maps.
|
||||
*/
|
||||
|
||||
(function () {
|
||||
'use strict';
|
||||
|
||||
L.Map = L.Map.extend({
|
||||
sync: function (map, options) {
|
||||
this._initSync();
|
||||
options = options || {};
|
||||
|
||||
// prevent double-syncing the map:
|
||||
var present = false;
|
||||
this._syncMaps.forEach(function (other) {
|
||||
if (map === other) {
|
||||
present = true;
|
||||
}
|
||||
});
|
||||
|
||||
if (!present) {
|
||||
this._syncMaps.push(map);
|
||||
}
|
||||
|
||||
if (!options.noInitialSync) {
|
||||
map.setView(this.getCenter(), this.getZoom(), {
|
||||
animate: false,
|
||||
reset: true
|
||||
});
|
||||
}
|
||||
return this;
|
||||
},
|
||||
|
||||
// unsync maps from each other
|
||||
unsync: function (map) {
|
||||
var self = this;
|
||||
|
||||
if (this._syncMaps) {
|
||||
this._syncMaps.forEach(function (synced, id) {
|
||||
if (map === synced) {
|
||||
self._syncMaps.splice(id, 1);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
return this;
|
||||
},
|
||||
|
||||
// overload methods on originalMap to replay on _syncMaps;
|
||||
_initSync: function () {
|
||||
if (this._syncMaps) {
|
||||
return;
|
||||
}
|
||||
var originalMap = this;
|
||||
|
||||
this._syncMaps = [];
|
||||
|
||||
L.extend(originalMap, {
|
||||
setView: function (center, zoom, options, sync) {
|
||||
if (!sync) {
|
||||
originalMap._syncMaps.forEach(function (toSync) {
|
||||
toSync.setView(center, zoom, options, true);
|
||||
});
|
||||
}
|
||||
return L.Map.prototype.setView.call(this, center, zoom, options);
|
||||
},
|
||||
|
||||
panBy: function (offset, options, sync) {
|
||||
if (!sync) {
|
||||
originalMap._syncMaps.forEach(function (toSync) {
|
||||
toSync.panBy(offset, options, true);
|
||||
});
|
||||
}
|
||||
return L.Map.prototype.panBy.call(this, offset, options);
|
||||
},
|
||||
|
||||
_onResize: function (event, sync) {
|
||||
if (!sync) {
|
||||
originalMap._syncMaps.forEach(function (toSync) {
|
||||
toSync._onResize(event, true);
|
||||
});
|
||||
}
|
||||
return L.Map.prototype._onResize.call(this, event);
|
||||
}
|
||||
});
|
||||
|
||||
originalMap.on('zoomend', function () {
|
||||
originalMap._syncMaps.forEach(function (toSync) {
|
||||
toSync.setView(originalMap.getCenter(), originalMap.getZoom(), {
|
||||
animate: false,
|
||||
reset: false
|
||||
});
|
||||
});
|
||||
}, this);
|
||||
|
||||
originalMap.dragging._draggable._updatePosition = function () {
|
||||
L.Draggable.prototype._updatePosition.call(this);
|
||||
var self = this;
|
||||
originalMap._syncMaps.forEach(function (toSync) {
|
||||
L.DomUtil.setPosition(toSync.dragging._draggable._element, self._newPos);
|
||||
toSync.fire('moveend');
|
||||
});
|
||||
};
|
||||
}
|
||||
});
|
||||
})();
|
||||
@@ -0,0 +1,35 @@
|
||||
.leaflet-control-layers-expanded.leaflet-control-layers-minimap {
|
||||
width: 240px;
|
||||
background: rgba(255, 255, 255, 0.85);
|
||||
box-shadow: 0 0 15px rgba(0, 0, 0, 0.2);
|
||||
|
||||
padding: 0;
|
||||
border: 4px solid rgba(255, 255, 255, 0.8);
|
||||
border-radius: 5px;
|
||||
overflow-x: hidden;
|
||||
}
|
||||
.leaflet-minimap-container {
|
||||
margin-bottom: 2px;
|
||||
position: relative;
|
||||
display: block;
|
||||
height: 110px;
|
||||
}
|
||||
.leaflet-minimap-container .leaflet-minimap-label {
|
||||
position: absolute;
|
||||
display: block;
|
||||
|
||||
height: 22px;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
padding: 2px 6px 2px 2px;
|
||||
background-color: rgba(0, 0, 0, 0.7);
|
||||
color: white;
|
||||
white-space: nowrap;
|
||||
}
|
||||
.leaflet-minimap-container .leaflet-minimap-label .leaflet-control-layers-selector {
|
||||
top: 3px;
|
||||
}
|
||||
.leaflet-minimap {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
Copyright (c) 2006, Ivan Sagalaev
|
||||
All rights reserved.
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
* Neither the name of highlight.js nor the names of its contributors
|
||||
may be used to endorse or promote products derived from this software
|
||||
without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND ANY
|
||||
EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE REGENTS AND CONTRIBUTORS BE LIABLE FOR ANY
|
||||
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
@@ -0,0 +1,127 @@
|
||||
/*
|
||||
|
||||
github.com style (c) Vasily Polovnyov <vast@whiteants.net>
|
||||
|
||||
*/
|
||||
|
||||
pre code {
|
||||
display: block; padding: 0.5em;
|
||||
color: #333;
|
||||
background: #f8f8ff
|
||||
}
|
||||
|
||||
pre .comment,
|
||||
pre .template_comment,
|
||||
pre .diff .header,
|
||||
pre .javadoc {
|
||||
color: #998;
|
||||
font-style: italic
|
||||
}
|
||||
|
||||
pre .keyword,
|
||||
pre .css .rule .keyword,
|
||||
pre .winutils,
|
||||
pre .javascript .title,
|
||||
pre .nginx .title,
|
||||
pre .subst,
|
||||
pre .request,
|
||||
pre .status {
|
||||
color: #333;
|
||||
font-weight: bold
|
||||
}
|
||||
|
||||
pre .number,
|
||||
pre .hexcolor,
|
||||
pre .ruby .constant {
|
||||
color: #099;
|
||||
}
|
||||
|
||||
pre .string,
|
||||
pre .tag .value,
|
||||
pre .phpdoc,
|
||||
pre .tex .formula {
|
||||
color: #d14
|
||||
}
|
||||
|
||||
pre .title,
|
||||
pre .id {
|
||||
color: #900;
|
||||
font-weight: bold
|
||||
}
|
||||
|
||||
pre .javascript .title,
|
||||
pre .lisp .title,
|
||||
pre .clojure .title,
|
||||
pre .subst {
|
||||
font-weight: normal
|
||||
}
|
||||
|
||||
pre .class .title,
|
||||
pre .haskell .type,
|
||||
pre .vhdl .literal,
|
||||
pre .tex .command {
|
||||
color: #458;
|
||||
font-weight: bold
|
||||
}
|
||||
|
||||
pre .tag,
|
||||
pre .tag .title,
|
||||
pre .rules .property,
|
||||
pre .django .tag .keyword {
|
||||
color: #000080;
|
||||
font-weight: normal
|
||||
}
|
||||
|
||||
pre .attribute,
|
||||
pre .variable,
|
||||
pre .lisp .body {
|
||||
color: #008080
|
||||
}
|
||||
|
||||
pre .regexp {
|
||||
color: #009926
|
||||
}
|
||||
|
||||
pre .class {
|
||||
color: #458;
|
||||
font-weight: bold
|
||||
}
|
||||
|
||||
pre .symbol,
|
||||
pre .ruby .symbol .string,
|
||||
pre .lisp .keyword,
|
||||
pre .tex .special,
|
||||
pre .prompt {
|
||||
color: #990073
|
||||
}
|
||||
|
||||
pre .built_in,
|
||||
pre .lisp .title,
|
||||
pre .clojure .built_in {
|
||||
color: #0086b3
|
||||
}
|
||||
|
||||
pre .preprocessor,
|
||||
pre .pi,
|
||||
pre .doctype,
|
||||
pre .shebang,
|
||||
pre .cdata {
|
||||
color: #999;
|
||||
font-weight: bold
|
||||
}
|
||||
|
||||
pre .deletion {
|
||||
background: #fdd
|
||||
}
|
||||
|
||||
pre .addition {
|
||||
background: #dfd
|
||||
}
|
||||
|
||||
pre .diff .change {
|
||||
background: #0086b3
|
||||
}
|
||||
|
||||
pre .chunk {
|
||||
color: #aaa
|
||||
}
|
||||
File diff suppressed because one or more lines are too long
@@ -0,0 +1,90 @@
|
||||
<!doctype html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<title>Leaflet Provider Demo</title>
|
||||
<meta charset="utf-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
|
||||
|
||||
<link rel="stylesheet" href="http://cdn.leafletjs.com/leaflet-0.7/leaflet.css" />
|
||||
|
||||
<style>
|
||||
html {
|
||||
height: 100%;
|
||||
-moz-box-sizing: border-box;
|
||||
-webkit-box-sizing: border-box;
|
||||
box-sizing: border-box;
|
||||
vertical-align: baseline;
|
||||
}
|
||||
body, #container { height: 100%; margin: 0; padding: 0;}
|
||||
.map { height: 100%; }
|
||||
|
||||
#info {
|
||||
background: rgba(255, 255, 255, 0.85);
|
||||
box-shadow: 0 0 15px rgba(0, 0, 0, 0.2);
|
||||
position: fixed;
|
||||
width: 50%;
|
||||
max-width: 600px;
|
||||
left: 45%;
|
||||
margin-left: -300px;
|
||||
padding: 6px 8px;
|
||||
|
||||
border-radius: 5px;
|
||||
font: 14px/16px Arial, Helvetica, sans-serif;
|
||||
}
|
||||
#info h4:first-child {
|
||||
margin: 0 0 5px;
|
||||
}
|
||||
#info h4 {
|
||||
margin: 5px 0 5px;
|
||||
}
|
||||
#info h4 code {
|
||||
font-weight: normal;
|
||||
}
|
||||
#info .provider-names {
|
||||
padding-bottom: 5px;
|
||||
display: block;
|
||||
padding-left: 15px;
|
||||
}
|
||||
#info pre {
|
||||
margin: 0;
|
||||
}
|
||||
#info pre code {
|
||||
font-size: 10px;
|
||||
overflow-x: auto;
|
||||
}
|
||||
</style>
|
||||
<!--Fork Me on Github ribbon, we're using the awsome version from simonwhitaker available at https://github.com/simonwhitaker/github-fork-ribbon-css -->
|
||||
<link rel="stylesheet" href="../css/gh-fork-ribbon.css" />
|
||||
<!--[if IE]>
|
||||
<link rel="stylesheet" href="../css/gh-fork-ribbon.ie.css" />
|
||||
<![endif]-->
|
||||
<link rel="stylesheet" href="highlightjs/github.css">
|
||||
<link rel="stylesheet" href="control.layers.minimap.css">
|
||||
</head>
|
||||
<body>
|
||||
<div class="github-fork-ribbon-wrapper left">
|
||||
<div class="github-fork-ribbon">
|
||||
<a href="https://github.com/leaflet-extras/leaflet-providers">Fork me on GitHub</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="info">
|
||||
<h4><a href="https://github.com/leaflet-extras/leaflet-providers">Leaflet-providers preview</a></h4>
|
||||
<p>
|
||||
This page shows mini maps for all the layers available in <a href="https://github.com/leaflet-extras/leaflet-providers">Leaflet-providers</a>.
|
||||
</p>
|
||||
</div>
|
||||
<div id="map" class="map"></div>
|
||||
|
||||
<script src="http://cdn.leafletjs.com/leaflet-0.7/leaflet-src.js"></script>
|
||||
<script src="../leaflet-providers.js"></script>
|
||||
|
||||
<script src="L.Map.Sync.js"></script>
|
||||
<script src="L.Control.Layers.Minimap.js"></script>
|
||||
|
||||
<script src="highlightjs/highlight.pack.js"></script>
|
||||
|
||||
<script src="preview.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,152 @@
|
||||
(function () {
|
||||
'use strict';
|
||||
|
||||
var map = new L.Map('map', {
|
||||
zoomControl: false,
|
||||
center: [48, -3],
|
||||
zoom: 5
|
||||
});
|
||||
|
||||
// save the options object while creating tilelayers to cleanly access it later.
|
||||
var origTileLayerInit = L.TileLayer.prototype.initialize;
|
||||
L.TileLayer.include({
|
||||
initialize: function (url, options) {
|
||||
this._options = options;
|
||||
origTileLayerInit.apply(this, arguments);
|
||||
}
|
||||
});
|
||||
var origProviderInit = L.TileLayer.Provider.prototype.initialize;
|
||||
L.TileLayer.Provider.include({
|
||||
initialize: function (arg) {
|
||||
this._providerName = arg;
|
||||
origProviderInit.apply(this, arguments);
|
||||
}
|
||||
});
|
||||
|
||||
var isOverlay = function (providerName) {
|
||||
var overlayPatterns = [
|
||||
'^(OpenWeatherMap|OpenSeaMap)',
|
||||
'OpenMapSurfer.AdminBounds',
|
||||
'Stamen.Toner(Hybrid|Lines|Labels)',
|
||||
'Acetate.(foreground|labels|roads)',
|
||||
];
|
||||
|
||||
return providerName.match('(' + overlayPatterns.join('|') + ')') !== null;
|
||||
};
|
||||
|
||||
var isIgnored = function (providerName) {
|
||||
var ignorePattern = /^(MapBox|OpenSeaMap)/;
|
||||
|
||||
return providerName.match(ignorePattern) !== null;
|
||||
};
|
||||
|
||||
var escapeHtml = function (string) {
|
||||
return string
|
||||
.replace(/&/g, '&')
|
||||
.replace(/</g, '<')
|
||||
.replace(/>/g, '>')
|
||||
.replace(/"/g, '"')
|
||||
.replace(/'/g, ''');
|
||||
};
|
||||
|
||||
// collect all layers available in the provider definition
|
||||
var baseLayers = {};
|
||||
var overlays = {};
|
||||
|
||||
var addLayer = function (name) {
|
||||
if (isOverlay(name)) {
|
||||
overlays[name] = L.tileLayer.provider(name);
|
||||
} else {
|
||||
baseLayers[name] = L.tileLayer.provider(name);
|
||||
}
|
||||
};
|
||||
|
||||
for (var provider in L.TileLayer.Provider.providers) {
|
||||
if (isIgnored(provider)) {
|
||||
continue;
|
||||
}
|
||||
if (L.TileLayer.Provider.providers[provider].variants) {
|
||||
for (var variant in L.TileLayer.Provider.providers[provider].variants) {
|
||||
addLayer(provider + '.' + variant);
|
||||
}
|
||||
} else {
|
||||
addLayer(provider);
|
||||
}
|
||||
}
|
||||
|
||||
L.control.layers.minimap(baseLayers, overlays, {
|
||||
collapsed: false
|
||||
}).addTo(map);
|
||||
baseLayers['OpenStreetMap.Mapnik'].addTo(map);
|
||||
|
||||
// Add the TileLayer source code control to the map
|
||||
map.addControl(new (L.Control.extend({
|
||||
options: {
|
||||
position: 'topleft'
|
||||
},
|
||||
onAdd: function (map) {
|
||||
var container = L.DomUtil.get('info');
|
||||
L.DomEvent.disableClickPropagation(container);
|
||||
|
||||
L.DomUtil.create('h4', null, container).innerHTML = 'Provider names for <code>leaflet-providers.js</code>';
|
||||
var providerNames = L.DomUtil.create('code', 'provider-names', container);
|
||||
|
||||
L.DomUtil.create('h4', '', container).innerHTML = 'Plain JavaScript:';
|
||||
var pre = L.DomUtil.create('pre', null, container);
|
||||
var code = L.DomUtil.create('code', 'javascript', pre);
|
||||
|
||||
var update = function (event) {
|
||||
code.innerHTML = '';
|
||||
|
||||
var names = [];
|
||||
|
||||
// loop over the layers in the map and add the JS
|
||||
for (var key in map._layers) {
|
||||
var layer = map._layers[key];
|
||||
|
||||
names.push(layer._providerName);
|
||||
var layerName = layer._providerName.replace('.', '_');
|
||||
|
||||
// do not add the layer currently being removed
|
||||
if (event && event.type === 'layerremove' && layer === event.layer) {
|
||||
continue;
|
||||
}
|
||||
var tileLayerCode = 'var ' + layerName + ' = L.tileLayer(\'' + layer._url + '\', {\n';
|
||||
|
||||
var options = layer._options;
|
||||
var first = true;
|
||||
for (var option in options) {
|
||||
if (first) {
|
||||
first = false;
|
||||
} else {
|
||||
tileLayerCode += ',\n';
|
||||
}
|
||||
tileLayerCode += '\t' + option + ': ';
|
||||
if (typeof options[option] === 'string') {
|
||||
//jshint quotmark:double
|
||||
tileLayerCode += "'" + escapeHtml(options[option]) + "'";
|
||||
//jshint quotmark:single
|
||||
} else {
|
||||
tileLayerCode += options[option];
|
||||
}
|
||||
}
|
||||
tileLayerCode += '\n});\n';
|
||||
code.innerHTML += tileLayerCode;
|
||||
|
||||
providerNames.innerHTML = names.join(', ');
|
||||
}
|
||||
/* global hljs:true */
|
||||
hljs.highlightBlock(code);
|
||||
};
|
||||
|
||||
map.on({
|
||||
'layeradd': update,
|
||||
'layerremove': update
|
||||
});
|
||||
update();
|
||||
|
||||
return container;
|
||||
}
|
||||
}))());
|
||||
|
||||
})();
|
||||
@@ -0,0 +1,132 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<script src="http://cdn.leafletjs.com/leaflet-0.7/leaflet.js"></script>
|
||||
<link rel="stylesheet" href="http://cdn.leafletjs.com/leaflet-0.7/leaflet.css" />
|
||||
|
||||
<script src="leaflet-providers/leaflet-providers.js"></script>
|
||||
|
||||
<script src="Leaflet-MiniMap/src/Control.MiniMap.js"></script>
|
||||
<link rel="stylesheet" href="Leaflet-MiniMap/src/Control.MiniMap.css" />
|
||||
|
||||
<script type="text/javascript" charset="utf-8">
|
||||
// Function to parse the URL search query parameters.
|
||||
// It will give A, B, C given http://www.somelink.com?lat=A&lon=B&zoom=C
|
||||
// See "http://javascriptproductivity.blogspot.com/" +
|
||||
// "2013/02/get-url-variables-with-javascript.html".
|
||||
function getParams(){
|
||||
// Make an object variable to hold
|
||||
// the parsed URL parameters' keys and vlaues.
|
||||
var params = {};
|
||||
|
||||
// Remove the '?' character after the base url.
|
||||
// x.substring(i) will return the substring of x starting at index i
|
||||
// up to the end of the string.
|
||||
// Drupal CMS might have a path like this (two '?' characters):
|
||||
// mapParser.html?t=E3OD?lat=14.6760413&lon=121.0437003&...
|
||||
// We need to handle this case also.
|
||||
var lastIndex = window.location.search.lastIndexOf("?")
|
||||
|
||||
// Get the substring not including any '?' character.
|
||||
var query_string = window.location.search.substring(lastIndex + 1);
|
||||
|
||||
// Explode the string using the '&' character.
|
||||
var query_string_parts = query_string.split('&');
|
||||
|
||||
// Traverse the exploded tokens.
|
||||
for(i in query_string_parts) {
|
||||
// Explode the string using '=' to isolate keys and values.
|
||||
key_value = query_string_parts[i].split('=');
|
||||
|
||||
// Insert a new key and set it to the current parsed value.
|
||||
params[key_value[0]] = key_value[1];
|
||||
}
|
||||
|
||||
// Return the parameter object contianing the keys and values.
|
||||
return params;
|
||||
}
|
||||
</script>
|
||||
<style>
|
||||
.leaflet-popup-content {
|
||||
text-align: center;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div id='map_container' style="width:95%px; height:590px;" data-zoom=""></div>
|
||||
|
||||
<script type="text/javascript">
|
||||
// Get the DOM node to which we will append the map.
|
||||
// In our setup the map container is a DIV element.
|
||||
var mapDiv = document.getElementById("map_container");
|
||||
|
||||
// Parse the query parameters in the URL to obtain the
|
||||
// LAT, LON, and ZOOM values.
|
||||
queryString = getParams();
|
||||
|
||||
// Convert the parameters to their numeric equivalent.
|
||||
// Otherwise, it will not work.
|
||||
var latitude = Number(queryString["lat"]);
|
||||
var longitude = Number(queryString["lon"]);
|
||||
|
||||
// Retrieve and adjust the map's height by 10px for better layout.
|
||||
var mapHeight = Number(queryString["height"]) - 10;
|
||||
mapDiv.style.height = String(mapHeight) + "px";
|
||||
|
||||
// Retrieve the zoom level.
|
||||
var zoom = Number(queryString["zoom"]);
|
||||
|
||||
// Retrive the popup text that will be used by the marker.
|
||||
var popUpText = queryString["text"];
|
||||
|
||||
// Retrieve the Base Map's Tile to be used.
|
||||
var tile = queryString["tile"];
|
||||
|
||||
// Retrieve the information about the inclusion of Overview map.
|
||||
var minimap = queryString["minimap"];
|
||||
|
||||
// Create a map in the the target DOM container.
|
||||
// Set the view to a given place and zoom value.
|
||||
var map = L.map('map_container').setView([latitude, longitude], zoom);
|
||||
|
||||
// Choose the Map Tile provider "Esri.WorldTopoMap"
|
||||
var mapTileProvider = tile;
|
||||
|
||||
// Set the base map.
|
||||
var mapTile = L.tileLayer.provider(mapTileProvider, { attribution: "Map Tile: " + mapTileProvider });
|
||||
mapTile.addTo(map);
|
||||
|
||||
// Add a marker in the given location.
|
||||
var p1 = L.marker([latitude, longitude]);
|
||||
p1.addTo(map);
|
||||
|
||||
// If the pop-up text is specified.
|
||||
if (popUpText != '') {
|
||||
// Replace the %20 HTML Entity by an empty space.
|
||||
// %20 is the result of texts being piped via URL.
|
||||
popUpText = popUpText.replace(/%20/g, ' ');
|
||||
|
||||
// Bind the text to the current marker.
|
||||
p1.bindPopup(popUpText);
|
||||
}
|
||||
|
||||
// Check if MiniMap needs to be shown also.
|
||||
if (minimap == "on") {
|
||||
// Create a new Tile Layer for the MiniMap.
|
||||
// Per documentation, do not reuse the existing Tile object
|
||||
// to avoid rendering issues.
|
||||
var mapTile2 = L.tileLayer.provider(mapTileProvider);
|
||||
var miniMap = new L.Control.MiniMap(mapTile2).addTo(map);
|
||||
}
|
||||
|
||||
// Initialize the zoom data attribute.
|
||||
mapDiv.setAttribute("data-zoom", map.getZoom());
|
||||
|
||||
// Add an event listener that will keep track the changes in the
|
||||
// map's zoom levels and it will update the data attribute accordingly.
|
||||
map.on('zoomend', function(e) {
|
||||
mapDiv.setAttribute("data-zoom", map.getZoom());
|
||||
});
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
Reference in New Issue
Block a user