1. Import

This commit is contained in:
2026-03-29 10:34:57 +02:00
parent b0e00c1259
commit a1129565af
4899 changed files with 3007593 additions and 0 deletions

View File

@@ -0,0 +1,35 @@
{
"rules": {
"camelcase": 2,
"quotes": [2, "single", "avoid-escape"],
"indent": 2,
"space-before-function-paren": [2, "never"],
"space-in-parens": 2,
"object-curly-spacing": 2,
"space-before-blocks": 2,
"keyword-spacing": 2,
"no-lonely-if": 2,
"comma-spacing": [2, {"after": true}],
"comma-style": 2,
"no-underscore-dangle": 0,
"no-constant-condition": 0,
"no-multi-spaces": 2,
"strict": 0,
"key-spacing": 2,
"no-shadow": 0,
"no-console": 2,
"no-trailing-spaces": 2,
},
"globals": {
"L": true,
"module": true,
"define": true
},
"plugins": [
"html"
],
"settings": {
"html/report-bad-indent": 2,
"html/indent": "space"
}
}

View File

@@ -0,0 +1 @@
node_modules

View File

@@ -0,0 +1,5 @@
language: node_js
sudo: false
node_js:
- "stable"

View File

@@ -0,0 +1,61 @@
.leaflet-control-layers-toggle.leaflet-layerstree-named-toggle {
margin: 2px 5px;
width: auto;
height: auto;
background-image: none;
}
.leaflet-layerstree-node {
}
.leaflet-layerstree-header input{
margin-left: 0px;
}
.leaflet-layerstree-header {
}
.leaflet-layerstree-header-pointer {
cursor: pointer;
}
.leaflet-layerstree-header label {
display: inline-block;
cursor: pointer;
}
.leaflet-layerstree-header-label {
}
.leaflet-layerstree-header-name {
}
.leaflet-layerstree-header-space {
}
.leaflet-layerstree-children {
padding-left: 10px;
}
.leaflet-layerstree-children-nopad {
padding-left: 0px;
}
.leaflet-layerstree-closed {
}
.leaflet-layerstree-opened {
}
.leaflet-layerstree-hide {
display: none;
}
.leaflet-layerstree-nevershow {
display: none;
}
.leaflet-layerstree-expand-collapse {
cursor: pointer;
}

View File

@@ -0,0 +1,396 @@
/*
* Control like L.Control.Layers, but showing layers in a tree.
* Do not forget to include the css file.
*/
(function(L) {
if (typeof L === 'undefined') {
throw new Error('Leaflet must be included first');
}
/*
* L.Control.Layers.Tree extends L.Control.Layers because it reuses
* most of its functionality. Only the HTML creation is different.
*/
L.Control.Layers.Tree = L.Control.Layers.extend({
options: {
closedSymbol: '+',
openedSymbol: '−',
spaceSymbol: ' ',
selectorBack: false,
namedToggle: false,
collapseAll: '',
expandAll: '',
},
// Class names are error prone texts, so write them once here
_initClassesNames: function() {
this.cls = {
children: 'leaflet-layerstree-children',
childrenNopad: 'leaflet-layerstree-children-nopad',
hide: 'leaflet-layerstree-hide',
closed: 'leaflet-layerstree-closed',
opened: 'leaflet-layerstree-opened',
space: 'leaflet-layerstree-header-space',
pointer: 'leaflet-layerstree-header-pointer',
header: 'leaflet-layerstree-header',
neverShow: 'leaflet-layerstree-nevershow',
node: 'leaflet-layerstree-node',
name: 'leaflet-layerstree-header-name',
label: 'leaflet-layerstree-header-label',
};
},
initialize: function(baseTree, overlaysTree, options) {
this._scrollTop = 0;
this._initClassesNames();
this._baseTree = null;
this._overlaysTree = null;
L.Util.setOptions(this, options);
L.Control.Layers.prototype.initialize.call(this, null, null, options);
this._setTrees(baseTree, overlaysTree);
},
setBaseTree: function(tree) {
return this._setTrees(tree);
},
setOverlayTree: function(tree) {
return this._setTrees(undefined, tree);
},
addBaseLayer: function(layer, name) {
throw 'addBaseLayer is disabled';
},
addOverlay: function(layer, name) {
throw 'addOverlay is disabled';
},
removeLayer: function(layer) {
throw 'removeLayer is disabled';
},
collapse: function() {
this._scrollTop = this._sect().scrollTop;
return L.Control.Layers.prototype.collapse.call(this);
},
expand: function() {
var ret = L.Control.Layers.prototype.expand.call(this);
this._sect().scrollTop = this._scrollTop;
},
onAdd: function(map) {
function changeName(layer) {
if (layer._layersTreeName) {
toggle.innerHTML = layer._layersTreeName;
}
}
var ret = L.Control.Layers.prototype.onAdd.call(this, map);
if (this.options.namedToggle) {
var toggle = this._container.getElementsByClassName('leaflet-control-layers-toggle')[0];
L.DomUtil.addClass(toggle, 'leaflet-layerstree-named-toggle');
// Start with this value...
map.eachLayer(function(layer) {changeName(layer);});
// ... and change it whenever the baselayer is changed.
map.on('baselayerchange', function(e) {changeName(e.layer);}, this);
}
return ret;
},
// Expands the whole tree (base other overlays)
expandTree: function(overlay) {
var container = overlay ? this._overlaysList : this._baseLayersList;
if (container) {
this._applyOnTree(container, false);
}
return this._localExpand();
},
// Collapses the whole tree (base other overlays)
collapseTree: function(overlay) {
var container = overlay ? this._overlaysList : this._baseLayersList;
if (container) {
this._applyOnTree(container, true);
}
return this._localExpand();
},
// Expands the tree, only to show the selected inputs
expandSelected: function(overlay) {
function iter(el) {
// Function to iterate the whole DOM upwards
var p = el.parentElement;
if (p) {
if (L.DomUtil.hasClass(p, that.cls.children) &&
!L.DomUtil.hasClass(el, that.cls.childrenNopad)) {
L.DomUtil.removeClass(p, hide);
}
if (L.DomUtil.hasClass(p, that.cls.node)) {
var h = p.getElementsByClassName(that.cls.header)[0];
that._applyOnTree(h, false);
}
iter(p);
}
}
var that = this;
var container = overlay ? this._overlaysList : this._baseLayersList;
if (!container) return this;
var hide = this.cls.hide;
var inputs = this._layerControlInputs || container.getElementsByTagName('input');
for (var i = 0; i < inputs.length; i++) {
// Loop over every (valid) input.
var input = inputs[i];
if (this._getLayer && !!this._getLayer(input.layerId).overlay != !!overlay) continue
if (input.checked) {
// Get out of the header,
// to not open the posible (but rare) children
iter(input.parentElement.parentElement.parentElement.parentElement);
}
}
return this._localExpand();
},
// "private" methods, not exposed in the API
_sect: function() {
// to keep compatibility after 1.3 https://github.com/Leaflet/Leaflet/pull/6380
return this._section || this._form;
},
_setTrees: function(base, overlays) {
var id = 0; // to keep unique id
function iterate(tree, output, overlays) {
if (tree && tree.layer) {
if (!overlays) {
tree.layer._layersTreeName = tree.name || tree.label;
}
output[id++] = tree.layer;
}
if (tree && tree.children && tree.children.length) {
tree.children.forEach(function(child) {
iterate(child, output, overlays);
});
}
return output;
}
// We accept arrays, but convert into an object with children
function forArrays(input) {
if (Array.isArray(input)) {
return {noShow: true, children: input};
} else {
return input
}
}
// Clean everything, and start again.
if (this._layerControlInputs) {
this._layerControlInputs = [];
}
for (var i = 0; i < this._layers.length; ++i) {
this._layers[i].layer.off('add remove', this._onLayerChange, this);
}
this._layers = [];
if (base !== undefined) this._baseTree = forArrays(base);
if (overlays !== undefined) this._overlaysTree = forArrays(overlays);
var bflat = iterate(this._baseTree, {});
for (var i in bflat) {
this._addLayer(bflat[i], i);
}
var oflat = iterate(this._overlaysTree, {}, true);
for (i in oflat) {
this._addLayer(oflat[i], i, true);
}
return (this._map) ? this._update() : this;
},
// Used to update the vertical scrollbar
_localExpand: function() {
if (this._map && L.DomUtil.hasClass(this._container, 'leaflet-control-layers-expanded')) {
var top = this._sect().scrollTop;
this.expand();
this._sect().scrollTop = top; // to keep the scroll location
this._scrollTop = top;
}
return this;
},
// collapses or expands the tree in the containter.
_applyOnTree: function(container, collapse) {
var iters = [
{cls: this.cls.children, hide: collapse},
{cls: this.cls.opened, hide: collapse},
{cls: this.cls.closed, hide: !collapse},
];
iters.forEach(function(it) {
var els = container.getElementsByClassName(it.cls);
for (var i = 0; i < els.length; i++) {
var el = els[i];
if (L.DomUtil.hasClass(el, this.cls.childrenNopad)) {
// do nothing
} else if (it.hide) {
L.DomUtil.addClass(el, this.cls.hide);
} else {
L.DomUtil.removeClass(el, this.cls.hide);
}
}
}, this);
},
// it is called in the original _update, and shouldn't do anything.
_addItem: function(obj) {
},
// overwrite _update function in Control.Layers
_update: function() {
if (!this._container) { return this; }
L.Control.Layers.prototype._update.call(this);
this._addTreeLayout(this._baseTree, false);
this._addTreeLayout(this._overlaysTree, true);
return this._localExpand();
},
// Create the DOM objects for the tree
_addTreeLayout: function(tree, overlay) {
if (!tree) return;
var container = overlay ? this._overlaysList : this._baseLayersList;
this._expandCollapseAll(overlay, this.options.collapseAll, this.collapseTree);
this._expandCollapseAll(overlay, this.options.expandAll, this.expandTree);
this._iterateTreeLayout(tree, container, overlay, tree.noShow)
if (this._checkDisabledLayers) {
// to keep compatibility
this._checkDisabledLayers();
}
},
// Create the "Collapse all" or expand, if needed.
_expandCollapseAll: function(overlay, text, fn, ctx) {
var container = overlay ? this._overlaysList : this._baseLayersList;
ctx = ctx ? ctx : this;
if (text) {
var o = document.createElement('div');
o.className = 'leaflet-layerstree-expand-collapse';
container.appendChild(o);
o.innerHTML = text;
o.tabIndex = 0;
L.DomEvent.on(o, 'click keydown', function(e) {
if (e.type !== 'keydown' || e.keyCode === 32) {
o.blur()
fn.call(ctx, overlay);
this._localExpand();
}
}, this);
}
},
// recursive funtion to create the DOM children
_iterateTreeLayout: function(tree, container, overlay, noShow) {
if (!tree) return;
function creator(type, cls, append, innerHTML) {
var obj = L.DomUtil.create(type, cls, append);
if (innerHTML) obj.innerHTML = innerHTML;
return obj;
}
// create the header with it fields
var header = creator('div', this.cls.header, container);
var sel = creator('span');
var entry = creator('span');
var closed = creator('span', this.cls.closed, sel, this.options.closedSymbol);
var opened = creator('span', this.cls.opened, sel, this.options.openedSymbol);
var space = creator('span', this.cls.space, null, this.options.spaceSymbol);
if (this.options.selectorBack) {
sel.insertBefore(space, closed);
header.appendChild(entry);
header.appendChild(sel);
} else {
sel.appendChild(space);
header.appendChild(sel);
header.appendChild(entry);
}
var hide = this.cls.hide; // To toggle state
// create the children group, with the header event click
if (tree.children) {
var children = creator('div', this.cls.children, container);
var sensible = tree.layer ? sel : header;
L.DomUtil.addClass(sensible, this.cls.pointer);
sensible.tabIndex = 0;
L.DomEvent.on(sensible, 'click keydown', function(e) {
if (e.type === 'keydown' && e.keyCode !== 32) {
return
}
sensible.blur();
if (L.DomUtil.hasClass(opened, hide)) {
// it is not opened, so open it
L.DomUtil.addClass(closed, hide);
L.DomUtil.removeClass(opened, hide);
L.DomUtil.removeClass(children, hide);
} else {
// close it
L.DomUtil.removeClass(closed, hide);
L.DomUtil.addClass(opened, hide);
L.DomUtil.addClass(children, hide);
}
this._localExpand();
}, this);
tree.children.forEach(function(child) {
var node = creator('div', this.cls.node, children)
this._iterateTreeLayout(child, node, overlay);
}, this);
} else {
// no children, so the selector makes no sense.
L.DomUtil.addClass(sel, this.cls.neverShow);
}
// create the input and label, as in Control.Layers
var label = creator(tree.layer ? 'label' : 'span', this.cls.label, entry);
if (tree.layer) {
// now create the element like in _addItem
var checked = this._map.hasLayer(tree.layer)
var input;
var radioGroup = overlay ? tree.radioGroup : 'leaflet-base-layers_' + L.Util.stamp(this);
if (radioGroup) {
input = this._createRadioElement(radioGroup, checked);
} else {
input = this._createCheckboxElement(checked);
}
if (this._layerControlInputs) {
// to keep compatibility with 1.0.3
this._layerControlInputs.push(input);
}
input.layerId = L.Util.stamp(tree.layer);
L.DomEvent.on(input, 'click', this._onInputClick, this);
label.appendChild(input);
}
var name = creator('span', this.cls.name, label, tree.label);
L.DomUtil.addClass(closed, hide);
if (noShow) {
L.DomUtil.addClass(header, this.cls.neverShow);
L.DomUtil.addClass(children, this.cls.childrenNopad);
}
},
_createCheckboxElement: function(checked) {
var input = document.createElement('input');
input.type = 'checkbox';
input.className = 'leaflet-control-layers-selector';
input.defaultChecked = checked;
return input;
},
});
L.control.layers.tree = function(base, overlays, options) {
return new L.Control.Layers.Tree(base, overlays, options);
}
})(L);

View File

@@ -0,0 +1,29 @@
BSD 3-Clause License
Copyright (c) 2017, Javier Jimenez Shaw
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 the copyright holder 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 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.

View File

@@ -0,0 +1,125 @@
# Leaflet.Control.Layers.Tree
[![Build Status](https://travis-ci.org/jjimenezshaw/Leaflet.Control.Layers.Tree.svg)](https://travis-ci.org/jjimenezshaw/Leaflet.Control.Layers.Tree)
[![NPM version](https://img.shields.io/npm/v/leaflet.control.layers.tree.svg)](https://www.npmjs.com/package/leaflet.control.layers.tree)
[![License](https://img.shields.io/badge/license-BSD--3--Clause-blue.svg?style=flat)](LICENSE)
[![Leaflet 1.x compatible!](https://img.shields.io/badge/Leaflet%201.x-%E2%9C%93-1EB300.svg?style=flat)](http://leafletjs.com/reference.html)
A Tree Layers Control for Leaflet.
## Description
This plugin extends [`Control.Layers`](http://leafletjs.com/reference-1.4.0.html#control-layers) allowing a tree structure for the layers layout. In `Control.Layers` you can only display a flat list of layers (baselayers and overlays), that is usually enough for small sets. If you have a long list of baselayers or overlays, and you want to organize them in a tree (allowing the user collapse and expand branches), this is a good option.
[Some live examples here](https://jjimenezshaw.github.io/Leaflet.Control.Layers.Tree/examples/)
## Installation
Using npm for browserify `npm install leaflet.control.layers.tree` (and `require('leaflet.control.layers.tree')`), or just download `L.Control.Layers.Tree.js` and `L.Control.Layers.Tree.css` and add a script and link tag for it in your html.
## Compatibility
This plugin has been tested with Leaflet 1.0.3, 1.1.0, 1.2.0, 1.3.1. and 1.4.0
## Usage
1. Create your layers. Do this as usual.
2. Create your layers tree, like the one just below.
3. Create the control and add to the map: `L.control.layers.tree(baseTree, overalysTree, options).addTo(map);`
4. Voilà!
```javascript
var baseTree = {
label: 'Base Layers',
children: [
{
label: 'World &#x1f5fa;',
children: [
{ label: 'OpenStreetMap', layer: osm },
{ label: 'Esri', layer: esri },
{ label: 'Google Satellite', layer: g_s },
/* ... */
]
},
{
label: 'Europe',
children: [
{ label: 'France', layer: france },
{ label: 'Germany', layer: germany },
{ label: 'Spain', layer: spain },
/* ... */
]
},
{
label: 'USA',
children: [
{
label: 'General',
children: [
{ label: 'Nautical', layer: usa_naut },
{ label: 'Satellite', layer: usa_sat },
{ label: 'Topographical', layer: usa_topo },
]
},
{
label: 'States',
children: [
{ label: 'CA', layer: usa_ca },
{ label: 'NY', layer: usa_ny },
/* ... */
]
}
]
},
]
};
```
![small tree sample](smalltree.png)
## API
### `L.Control.Layers.Tree`
The main (and only) 'class' involved in this plugin. It exteds `L.Control.Layers`, so most of its methods are available. `addBaseLayer`, `addOverlay` and `removeLayer` are non usable in `L.Control.Layers.Tree`.
#### `L.control.layers.tree(baseTree, overlayTree, options)`
Creates the control. The arguments are:
* `baseTree`: `<Object>` or `<Array>` Tree defining the base layers (like the one above). You can also provide an `Array` of nodes, if you want to start with a flat level.
* `overlayTree`: `<Object>` or `<Array>` Similar than baseTree, but for overlays.
* `options`: `<Object>` specific options for the tree. See that it includes `L.Control.Layer` [options](http://leafletjs.com/reference-1.4.0.html#control-layers)
##### constructor options
* `closedSymbol`: `<String>` Symbol displayed on a closed node (that you can click to open). Default '+'.
* `openedSymbol`: `<String>` Symbol displayed on a opened node (that you can click to close). Default '&minus;' (`&minus;`).
* `spaceSymbol`: `<String>` Symbol between the closed or opened symbol, and the text. Default ' ' (a normal space).
* `selectorBack`: `<Boolean>` Flag to indicate if the selector (+ or &minus;) is _after_ the text. Default 'false'.
* `namedToggle`: `<Boolean>` Flag to replace the toggle image (box with the layers image) with the 'name' of the selected base layer. If the `name` field is not present in the tree for this layer, `label` is used. See that you can show a different name when control is collapsed than the one that appears in the tree when it is expanded. Your node in the tree can be `{ label: 'OSM', name: 'OpenStreetMap', layer: layer }`. Default 'false'.
* `collapseAll`: `<String>` Text for an entry in control that collapses the tree (baselayers or overlays). If empty, no entry is created. Default ''.
* `expandAll`: `<String>` Text for an entry in control that expands the tree. If empty, no entry is created. Default ''.
See that those strings can be html code, with unicode, images or whatever you want.
#### `setBaseTree(tree)`
Resets the base layers tree (like in constructor, an `<Object>` or `<Array>`). Internally removes and adds all the layers, so you may be notified if you registered those events. Returns `this`.
#### `setOverlayTree(tree)`
Resets the overlay layers tree (like in constructor, an `<Object>` or `<Array>`). Internally removes and adds all the layers, so you may be notified if you registered those events. Returns `this`.
#### `expandTree(overlays)`
This method expands the tree. When `overlays` is `true` expands the overlays tree. Otherwise expands the baselayers tree. Returns `this`.
#### `collapseTree(overlays)`
This method collapses the tree. When `overlays` is `true` collapses the overlays tree. Otherwise collapses the baselayers tree. Returns `this`.
#### `expandSelected(overlays)`
This method expands only the selected item in the tree. When `overlays` is `true` affects the overlays tree. Otherwise affects the baselayers tree. Returns `this`.
## Tricks about the tree
The layers tree is a normal `Object`s tree like in the example above. The valid elements are:
* `children`: `<Array>` Array of children nodes for this node. Nothing special.
* `label`: `<String>` Text displayed in the tree for this node. It may contain HTML code.
* `layer`: `<L.Layer>` The layer itself. You can create with `L.tileLayer`, `L.marker`, or however you want.
* `name`: `<String>` Text displayed in the toggle when control is minimized. If not present, `label` is used. It makes sense only when `namedToggle` is `true`, and with base layers.
* `radioGroup`: `<String>` Text to identify different radio button groups. It is used in the `name` attribute in the [radio button](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input/radio). It is used only in the overlays layers (ignored in the base layers), allowing you to have radio buttons instead of checkboxes. See that radio groups cannot be unselected, so create a 'fake' layer (like `L.layersGroup([])`) if you want to disable it. Deafult `''` (that means checkbox).
You can see an example of a baselayers tree (the javascript code) above. You can provide a tree, or an array of trees.
Non leaf nodes (that is, those with `children`) can also have a layer. In this case you will be able to select the layer, and only the icon will collapse or expand this branch.
You can include HTML code, not only ascii chars, in the `label` attribute. It will be included as `innerHTML`. Be carefull with unicodes, because not every browser supports them all.
A leaf node without `layer` attribute is also posible. Only with `label`. This can be used to include special commands calling a javascript function, or a separator, or whatever you like. An example of separator node is
```javascript
{label: '<div class="leaflet-control-layers-separator"></div>'}
```

View File

@@ -0,0 +1,25 @@
{
"name": "leaflet.control.layers.tree",
"version": "0.1.1",
"description": "Control Layers in a Tree structure",
"homepage": "https://github.com/jjimenezshaw/Leaflet.Control.Layers.Tree",
"authors": [
"Javier Jimenez Shaw"
],
"main": "L.Control.Layers.Tree.js",
"style": "L.Control.Layers.Tree.css",
"keywords": [
"Leaflet",
"map",
"geo",
"tree",
"control",
"layers"
],
"license": "BSD-3-Clause",
"ignore": [
"**/.*",
"node_modules",
"test"
]
}

View File

@@ -0,0 +1,295 @@
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>Leaflet Layers Tree Demo: Airports in Europe</title>
<link rel="stylesheet" href="https://unpkg.com/leaflet@1.4.0/dist/leaflet.css" crossorigin=""/>
<script src="https://unpkg.com/leaflet@1.4.0/dist/leaflet-src.js" crossorigin=""></script>
<!--link rel="stylesheet" href="../../Leaflet/dist/leaflet.css" crossorigin=""/>
<script src="../../Leaflet/dist/leaflet-src.js" crossorigin=""></script-->
<style type="text/css">
html, body { width: 100%; height: 100%; margin: 0; }
#map { width: 100%; height: 100%; }
</style>
</head>
<body>
<div id="map"></div>
<link rel="stylesheet" href="../L.Control.Layers.Tree.css" crossorigin=""/>
<script src="../L.Control.Layers.Tree.js"></script>
<script type="text/javascript">
var center = [40, 0];
var osm = L.tileLayer(
'//{s}.tile.openstreetmap.org/{z}/{x}/{y}.png',
{attribution: '© OpenStreetMap contributors'}
);
var osmBw = L.tileLayer(
'http://{s}.tiles.wmflabs.org/bw-mapnik/{z}/{x}/{y}.png',
{attribution: '© OpenStreetMap contributors'}
);
var thunderAttr = {attribution: '© OpenStreetMap contributors. Tiles courtesy of Andy Allan'}
var transport = L.tileLayer(
'//{s}.tile.thunderforest.com/transport/{z}/{x}/{y}.png',
thunderAttr
);
var cycle = L.tileLayer(
'//{s}.tile.thunderforest.com/cycle/{z}/{x}/{y}.png',
thunderAttr
);
var map = L.map('map', {
layers: [osm],
center: center,
zoom: 5
});
var baseTree = {
label: 'BaseLayers',
noShow: true,
children: [
{
label: 'OpenStreeMap',
layer: osm,
children: [
{label: 'B&W', layer: osmBw, name: 'OpenStreeMap B&W'},
]
},
{
label: 'Thunder',
children: [
{label: 'Cycle', layer: cycle},
{label: 'Transport', layer: transport},
]
},
]
};
var ctl = L.control.layers.tree(baseTree, null,
{
collapsed: true,
namedToggle: true,
collapseAll: 'Collapse all',
expandAll: 'Expand all',
});
ctl.addTo(map).collapseTree().expandSelected();
var airportsEurope = [
/* start aiports from http://www.partow.net/miscellaneous/airportdatabase/#Download */
{label: 'GERMANY', children: [
{label: 'AACHEN - AAH', layer: L.marker([50.823000, 6.187000])},
{label: 'ALTENBURG - AOC', layer: L.marker([50.982000, 12.506000])},
{label: 'ARNSBERG - ZCA', layer: L.marker([51.483000, 7.899000])},
{label: 'AUGSBURG - AGB', layer: L.marker([48.425000, 10.932000])},
{label: 'BADEN-BADEN - ZCC', layer: L.marker([48.791000, 8.187000])},
{label: 'BAUTZEN - BBJ', layer: L.marker([51.193000, 14.520000])},
{label: 'BAYREUTH - BYU', layer: L.marker([49.984000, 11.638000])},
{label: 'BERLIN - SXF', layer: L.marker([52.380000, 13.523000])},
{label: 'BERLIN - THF', layer: L.marker([52.473000, 13.404000])},
{label: 'BERLIN - TXL', layer: L.marker([52.559000, 13.287000])},
{label: 'BORKUM - BMK', layer: L.marker([53.595000, 6.709000])},
{label: 'BRAUNSCHWEIG - BWE', layer: L.marker([52.319000, 10.556000])},
{label: 'BREMEN - BRE', layer: L.marker([53.047000, 8.787000])},
{label: 'BREMERHAVEN - BRV', layer: L.marker([53.503000, 8.573000])},
{label: 'BRUEGGEN - BGN', layer: L.marker([51.200000, 6.132000])},
{label: 'CELLE - ZCN', layer: L.marker([52.591000, 10.022000])},
{label: 'COLOGNE - CGN', layer: L.marker([50.866000, 7.143000])},
{label: 'DONAUESCHINGEN - ZQL', layer: L.marker([47.973000, 8.522000])},
{label: 'DORTMUND - DTM', layer: L.marker([51.518000, 7.612000])},
{label: 'DRESDEN - DRS', layer: L.marker([51.133000, 13.767000])},
{label: 'DUESSELDORF - DUS', layer: L.marker([51.289000, 6.767000])},
{label: 'EMDEN - EME', layer: L.marker([53.391000, 7.227000])},
{label: 'ERFURT - ERF', layer: L.marker([50.980000, 10.958000])},
{label: 'ESSEN - ESS', layer: L.marker([51.401000, 6.936000])},
{label: 'FRANKFURT - FRA', layer: L.marker([50.026000, 8.543000])},
{label: 'FRIEDRICHSHAFEN - FDH', layer: L.marker([47.671000, 9.511000])},
{label: 'FUERSTENFELDBRUCK - FEL', layer: L.marker([48.206000, 11.267000])},
{label: 'GEILENKIRCHEN - GKE', layer: L.marker([50.961000, 6.042000])},
{label: 'GIEBELSTADT - GHF', layer: L.marker([49.648000, 9.966000])},
{label: 'GOTHA OST - GWW', layer: L.marker([35.461000, -77.965000])},
{label: 'GUETERSLOH - GUT', layer: L.marker([51.923000, 8.306000])},
{label: 'HAHN - HHN', layer: L.marker([49.950000, 7.264000])},
{label: 'HAMBURG - HAM', layer: L.marker([53.630000, 9.988000])},
{label: 'HAMBURG - XFW', layer: L.marker([53.535000, 9.835000])},
{label: 'HANAU - ZNF', layer: L.marker([50.169000, 8.961000])},
{label: 'HANNOVER - HAJ', layer: L.marker([52.461000, 9.685000])},
{label: 'HEIDELBERG - QHD', layer: L.marker([49.393000, 8.652000])},
{label: 'HOF - HOQ', layer: L.marker([50.289000, 11.855000])},
{label: 'KASSEL - KSF', layer: L.marker([51.408000, 9.378000])},
{label: 'KIEL - KEL', layer: L.marker([54.379000, 10.145000])},
{label: 'KOBLENZ - ZNV', layer: L.marker([50.325000, 7.531000])},
{label: 'LAAGE - RLG', layer: L.marker([53.918000, 12.279000])},
{label: 'LAARBRUCH - LRC', layer: L.marker([51.602000, 6.143000])},
{label: 'LEIPZIG - LEJ', layer: L.marker([51.424000, 12.236000])},
{label: 'LEMWERDER - LEM', layer: L.marker([53.143000, 8.623000])},
{label: 'LUEBECK - LBC', layer: L.marker([53.805000, 10.719000])},
{label: 'MANNHEIM - MHG', layer: L.marker([49.473000, 8.514000])},
{label: 'MOENCHENGLADBACH - MGL', layer: L.marker([51.230000, 6.504000])},
{label: 'MUENSTER/OSNABRUECK - FMO', layer: L.marker([52.134000, 7.685000])},
{label: 'MUNICH - MUC', layer: L.marker([48.354000, 11.786000])},
{label: 'NORDERNEY - NRD', layer: L.marker([53.707000, 7.230000])},
{label: 'NUERNBERG - NUE', layer: L.marker([49.499000, 11.078000])},
{label: 'OBERPFAFFENHOFEN - OBF', layer: L.marker([48.081000, 11.283000])},
{label: 'PADERBORN - PAD', layer: L.marker([51.614000, 8.616000])},
{label: 'PARCHIM - SZW', layer: L.marker([53.427000, 11.783000])},
{label: 'RAMSTEIN - RMS', layer: L.marker([49.438000, 7.601000])},
{label: 'SAARBRUECKEN - SCN', layer: L.marker([49.214000, 7.109000])},
{label: 'SPANGDAHLEM - SPM', layer: L.marker([49.973000, 6.692000])},
{label: 'SPEYER - ZQC', layer: L.marker([49.302000, 8.451000])},
{label: 'STUTTGART - STR', layer: L.marker([48.690000, 9.222000])},
{label: 'TRIER - ZQF', layer: L.marker([49.863000, 6.789000])},
{label: 'WESTERLAND - GWT', layer: L.marker([54.913000, 8.340000])},
{label: 'WILHELMSHAVEN - WVN', layer: L.marker([53.505000, 8.053000])},
]},
{label: 'SPAIN', children: [
{label: 'ALICANTE - ALC', layer: L.marker([38.282000, -0.558000])},
{label: 'ALMERIA - LEI', layer: L.marker([36.844000, -2.370000])},
{label: 'AVILES - OVD', layer: L.marker([43.563000, -6.034000])},
{label: 'BADAJOZ - BJZ', layer: L.marker([38.891000, -6.821000])},
{label: 'BARCELONA - BCN', layer: L.marker([41.297000, 2.078000])},
{label: 'BILBAO - BIO', layer: L.marker([43.301000, -2.911000])},
{label: 'CORDOBA - ODB', layer: L.marker([37.842000, -4.849000])},
{label: 'GERONA - GRO', layer: L.marker([41.901000, 2.760000])},
{label: 'GRANADA - GRX', layer: L.marker([37.133000, -3.636000])},
{label: 'GRANADA - GRX', layer: L.marker([37.189000, -3.777000])},
{label: 'IBIZA - IBZ', layer: L.marker([38.873000, 1.373000])},
{label: 'JEREZ - XRY', layer: L.marker([36.744000, -6.060000])},
{label: 'LA CORUNA - LCG', layer: L.marker([43.302000, -8.377000])},
{label: 'MADRID - MAD', layer: L.marker([40.472000, -3.561000])},
{label: 'MADRID - TOJ', layer: L.marker([40.487000, -3.458000])},
{label: 'MALAGA - AGP', layer: L.marker([36.674000, -4.499000])},
{label: 'MENORCA - MAH', layer: L.marker([39.863000, 4.219000])},
{label: 'MURCIA - MJV', layer: L.marker([37.775000, -0.812000])},
{label: 'PALMA DE MALLORCA - PMI', layer: L.marker([39.550000, 2.733000])},
{label: 'PAMPLONA - PNA', layer: L.marker([42.770000, -1.646000])},
{label: 'REUS - REU', layer: L.marker([41.147000, 1.167000])},
{label: 'SALAMANCA - SLM', layer: L.marker([40.952000, -5.502000])},
{label: 'SAN SEBASTIAN - EAS', layer: L.marker([43.356000, -1.791000])},
{label: 'SANTA CRUZ DE LA PALMA - SPC', layer: L.marker([28.626000, -17.756000])},
{label: 'SANTANDER - SDR', layer: L.marker([43.427000, -3.820000])},
{label: 'SANTIAGO - SCQ', layer: L.marker([42.896000, -8.415000])},
{label: 'SEO DE URGEL - LEU', layer: L.marker([42.339000, 1.409000])},
{label: 'SEVILLA - OZP', layer: L.marker([37.175000, -5.616000])},
{label: 'SEVILLA - SVQ', layer: L.marker([37.418000, -5.893000])},
{label: 'VALENCIA - VLC', layer: L.marker([39.489000, -0.481000])},
{label: 'VALLADOLID - VLL', layer: L.marker([41.706000, -4.852000])},
{label: 'VIGO - VGO', layer: L.marker([42.232000, -8.627000])},
{label: 'VITORIA - VIT', layer: L.marker([42.883000, -2.724000])},
{label: 'ZARAGOZA - ZAZ', layer: L.marker([41.666000, -1.041000])},
]},
{label: 'FRANCE', children: [
{label: 'AGEN - AGF', layer: L.marker([44.175000, 0.591000])},
{label: 'AIX-LES-MILLES - QXB', layer: L.marker([43.505000, 5.368000])},
{label: 'ALBI - LBI', layer: L.marker([43.914000, 2.113000])},
{label: 'ANGOULEME - ANG', layer: L.marker([45.729000, 0.221000])},
{label: 'ANNECY - NCY', layer: L.marker([45.929000, 6.099000])},
{label: 'ANNEMASSE - QNJ', layer: L.marker([46.192000, 6.268000])},
{label: 'ARCACHON - XAC', layer: L.marker([44.596000, -1.111000])},
{label: 'AUBENAS-VALS-LANAS - OBS', layer: L.marker([44.544000, 4.372000])},
{label: 'AURILLAC - AUR', layer: L.marker([44.891000, 2.422000])},
{label: 'AUXERRE - AUF', layer: L.marker([47.850000, 3.497000])},
{label: 'AVIGNON - AVN', layer: L.marker([43.907000, 4.902000])},
{label: 'BEAUVAIS - BVA', layer: L.marker([49.454000, 2.113000])},
{label: 'BERGERAC - EGC', layer: L.marker([44.825000, 0.519000])},
{label: 'BEZIERS - BZR', layer: L.marker([43.324000, 3.356000])},
{label: 'BIARRITZ-BAYONNE - BIQ', layer: L.marker([43.468000, -1.523000])},
{label: 'BORDEAUX - BOD', layer: L.marker([44.828000, -0.716000])},
{label: 'BOURG - XBK', layer: L.marker([46.201000, 5.292000])},
{label: 'BOURGES - BOU', layer: L.marker([47.058000, 2.370000])},
{label: 'BREST - BES', layer: L.marker([48.448000, -4.418000])},
{label: 'BRIVE - BVE', layer: L.marker([45.151000, 1.469000])},
{label: 'CAEN - CFR', layer: L.marker([49.173000, -0.450000])},
{label: 'CALAIS - CQF', layer: L.marker([50.962000, 1.955000])},
{label: 'CANNES - CEQ', layer: L.marker([43.542000, 6.953000])},
{label: 'CARCASSONNE - CCF', layer: L.marker([43.216000, 2.306000])},
{label: 'CASTRES - DCM', layer: L.marker([43.556000, 2.289000])},
{label: 'CHALON - XCD', layer: L.marker([46.826000, 4.817000])},
{label: 'CHAMBERY - CMF', layer: L.marker([45.638000, 5.880000])},
{label: 'CHATEAUROUX - CHR', layer: L.marker([46.862000, 1.731000])},
{label: 'CHERBOURG - CER', layer: L.marker([49.650000, -1.470000])},
{label: 'CHOLET - CET', layer: L.marker([47.082000, -0.877000])},
{label: 'CLERMONT FERRAND - CFE', layer: L.marker([45.786000, 3.169000])},
{label: 'COGNAC - CNG', layer: L.marker([45.658000, -0.318000])},
{label: 'COLMAR - CMR', layer: L.marker([48.110000, 7.359000])},
{label: 'CREIL - CSF', layer: L.marker([49.253000, 2.519000])},
{label: 'DEAUVILLE - DOL', layer: L.marker([49.365000, 0.154000])},
{label: 'DIJON - DIJ', layer: L.marker([47.269000, 5.090000])},
{label: 'DINARD - DNR', layer: L.marker([48.588000, -2.080000])},
{label: 'DOLE - DLE', layer: L.marker([47.039000, 5.427000])},
{label: 'EPINAL - EPL', layer: L.marker([48.325000, 6.070000])},
{label: 'GRENOBLE - GNB', layer: L.marker([45.363000, 5.329000])},
{label: 'HYERES - TLN', layer: L.marker([43.097000, 6.146000])},
{label: 'LA ROCHE-SUR-YON - EDM', layer: L.marker([46.702000, -1.379000])},
{label: 'LA ROCHELLE - LRH', layer: L.marker([43.449000, 1.263000])},
{label: 'LANNION - LAI', layer: L.marker([48.754000, -3.471000])},
{label: 'LAVAL - LVA', layer: L.marker([48.031000, -0.743000])},
{label: 'LE CASTELLET - CTT', layer: L.marker([43.252000, 5.785000])},
{label: 'LE HAVRE - LEH', layer: L.marker([49.534000, 0.088000])},
{label: 'LE MANS - LME', layer: L.marker([47.949000, 0.202000])},
{label: 'LE PUY - LPY', layer: L.marker([45.079000, 3.765000])},
{label: 'LE TOURQUET - LTQ', layer: L.marker([50.515000, 1.627000])},
{label: 'LILLE - LIL', layer: L.marker([50.562000, 3.089000])},
{label: 'LIMOGES - LIG', layer: L.marker([45.863000, 1.179000])},
{label: 'LORIENT - LRT', layer: L.marker([47.761000, -3.440000])},
{label: 'LYON - LYN', layer: L.marker([45.728000, 4.945000])},
{label: 'LYON - LYS', layer: L.marker([45.726000, 5.091000])},
{label: 'MACON - QNX', layer: L.marker([46.295000, 4.796000])},
{label: 'MARSEILLE - MRS', layer: L.marker([43.436000, 5.214000])},
{label: 'MENDE - MEN', layer: L.marker([44.502000, 3.533000])},
{label: 'METZ - ETZ', layer: L.marker([48.982000, 6.254000])},
{label: 'METZ - MZM', layer: L.marker([49.072000, 6.132000])},
{label: 'MONTLUCON-GUERET - MCU', layer: L.marker([46.224000, 2.363000])},
{label: 'MONTLUCON - MCU', layer: L.marker([46.352000, 2.570000])},
{label: 'MONTPELLIER - MPL', layer: L.marker([43.576000, 3.963000])},
{label: 'MORLAIX - MXN', layer: L.marker([48.603000, -3.816000])},
{label: 'MOULINS - XMU', layer: L.marker([46.534000, 3.424000])},
{label: 'MULHOUSE - MLH', layer: L.marker([47.589000, 7.530000])},
{label: 'NANCY - ENC', layer: L.marker([48.692000, 6.230000])},
{label: 'NANTES - NTE', layer: L.marker([47.153000, -1.611000])},
{label: 'NEVERS - NVS', layer: L.marker([47.001000, 3.114000])},
{label: 'NICE - NCE', layer: L.marker([43.661000, 7.218000])},
{label: 'NIMES - FNI', layer: L.marker([43.757000, 4.416000])},
{label: 'NIORT - NIT', layer: L.marker([46.311000, -0.401000])},
{label: 'ORLEANS - ORE', layer: L.marker([47.988000, 1.761000])},
{label: 'PARIS - CDG', layer: L.marker([49.013000, 2.550000])},
{label: 'PARIS - LBG', layer: L.marker([48.969000, 2.441000])},
{label: 'PARIS - ORY', layer: L.marker([48.725000, 2.359000])},
{label: 'PAU - PUF', layer: L.marker([43.380000, -0.419000])},
{label: 'PERIGUEUX - PGX', layer: L.marker([45.198000, 0.816000])},
{label: 'PERPIGNAN - PGF', layer: L.marker([42.740000, 2.871000])},
{label: 'POITIERS - PIS', layer: L.marker([46.588000, 0.307000])},
{label: 'PONTOISE - POX', layer: L.marker([49.096000, 2.041000])},
{label: 'QUIMPER - UIP', layer: L.marker([47.975000, -4.168000])},
{label: 'REIMS - RHE', layer: L.marker([49.310000, 4.050000])},
{label: 'RENNES - RNS', layer: L.marker([48.069000, -1.735000])},
{label: 'ROANNE - RNE', layer: L.marker([46.058000, 4.001000])},
{label: 'ROCHEFORT - RCO', layer: L.marker([45.888000, -0.983000])},
{label: 'RODEZ - RDZ', layer: L.marker([44.408000, 2.482000])},
{label: 'ROUEN - URO', layer: L.marker([49.384000, 1.175000])},
{label: 'ROYAN - RYN', layer: L.marker([45.628000, -0.973000])},
{label: 'ST.-BRIEUC ARMOR - SBK', layer: L.marker([48.538000, -2.854000])},
{label: 'ST.-ETIENNE - EBU', layer: L.marker([45.540000, 4.296000])},
{label: 'ST.-NAZAIRE - SNR', layer: L.marker([47.312000, -2.149000])},
{label: 'STRASSBOURG - SXB', layer: L.marker([48.538000, 7.628000])},
{label: 'TARBES - LDE', layer: L.marker([43.179000, -0.006000])},
{label: 'TOULOUSE - TLS', layer: L.marker([43.629000, 1.364000])},
{label: 'TOURS - TUF', layer: L.marker([47.432000, 0.728000])},
{label: 'TOUSSOUS-LE-NOBLE - TNF', layer: L.marker([48.752000, 2.106000])},
{label: 'TROYES - QYR', layer: L.marker([48.323000, 4.018000])},
{label: 'VALENCE - VAF', layer: L.marker([44.921000, 4.970000])},
{label: 'VANNES - VNE', layer: L.marker([47.723000, -2.718000])},
{label: 'VICHY - VHY', layer: L.marker([46.169000, 3.404000])},
{label: 'VILEFRANCE - XVF', layer: L.marker([45.916000, 4.641000])},
]}
];
/* ends aiports */
ctl.setOverlayTree(airportsEurope).collapseTree(true).expandSelected(true);
</script>
</body>
</html>

View File

@@ -0,0 +1,79 @@
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>Leaflet Layers Tree Basic Demo</title>
<link rel="stylesheet" href="https://unpkg.com/leaflet@1.4.0/dist/leaflet.css" crossorigin=""/>
<script src="https://unpkg.com/leaflet@1.4.0/dist/leaflet-src.js" crossorigin=""></script>
<style type="text/css">
html, body { width: 100%; height: 100%; margin: 0; }
#map { width: 100%; height: 100%; }
</style>
</head>
<body>
<div id="map"></div>
<link rel="stylesheet" href="../L.Control.Layers.Tree.css" crossorigin=""/>
<script src="../L.Control.Layers.Tree.js"></script>
<script type="text/javascript">
var center = [40, 0];
// Define some base layers
var osm = L.tileLayer(
'//{s}.tile.openstreetmap.org/{z}/{x}/{y}.png',
{attribution: '© OpenStreetMap contributors'}
);
var osmBw = L.tileLayer(
'http://{s}.tiles.wmflabs.org/bw-mapnik/{z}/{x}/{y}.png',
{attribution: '© OpenStreetMap contributors'}
);
var otopomap = L.tileLayer(
'//{s}.tile.opentopomap.org/{z}/{x}/{y}.png',
{attribution: '© OpenStreetMap contributors. OpenTopoMap.org'}
);
var thunderAttr = {attribution: '© OpenStreetMap contributors. Tiles courtesy of Andy Allan'}
var transport = L.tileLayer(
'//{s}.tile.thunderforest.com/transport/{z}/{x}/{y}.png',
thunderAttr
);
var cycle = L.tileLayer(
'//{s}.tile.thunderforest.com/cycle/{z}/{x}/{y}.png',
thunderAttr
);
// The tree containing the layers
var baseTree = [
{
label: 'OpenStreeMap',
children: [
{label: 'OSM', layer: osm, name: 'OpenStreeMap'},
{label: 'B&W', layer: osmBw, name: 'OpenStreeMap <b>B&W</b>'},
{label: 'OpenTopoMap', layer: otopomap, name: 'Topographic - OSM'},
]
},
{
label: 'Thunder',
children: [
{label: 'Cycle', layer: cycle},
{label: 'Transport', layer: transport},
]
},
];
// The map
var map = L.map('map', {
layers: [osm],
center: center,
zoom: 5
});
L.control.layers.tree(baseTree).addTo(map);
</script>
</body>
</html>

View File

@@ -0,0 +1,79 @@
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>Leaflet Layers Tree Basic Demo</title>
<link rel="stylesheet" href="https://unpkg.com/leaflet@1.3.4/dist/leaflet.css" crossorigin=""/>
<script src="https://unpkg.com/leaflet@1.3.4/dist/leaflet-src.js" crossorigin=""></script>
<style type="text/css">
html, body { width: 100%; height: 100%; margin: 0; }
#map { width: 100%; height: 100%; }
</style>
</head>
<body>
<div id="map"></div>
<link rel="stylesheet" href="../L.Control.Layers.Tree.css" crossorigin=""/>
<script src="../L.Control.Layers.Tree.js"></script>
<script type="text/javascript">
var center = [40, 0];
// Define some base layers
var osm = L.tileLayer(
'//{s}.tile.openstreetmap.org/{z}/{x}/{y}.png',
{attribution: '© OpenStreetMap contributors'}
);
var osmBw = L.tileLayer(
'http://{s}.tiles.wmflabs.org/bw-mapnik/{z}/{x}/{y}.png',
{attribution: '© OpenStreetMap contributors'}
);
var otopomap = L.tileLayer(
'//{s}.tile.opentopomap.org/{z}/{x}/{y}.png',
{attribution: '© OpenStreetMap contributors. OpenTopoMap.org'}
);
var thunderAttr = {attribution: '© OpenStreetMap contributors. Tiles courtesy of Andy Allan'}
var transport = L.tileLayer(
'//{s}.tile.thunderforest.com/transport/{z}/{x}/{y}.png',
thunderAttr
);
var cycle = L.tileLayer(
'//{s}.tile.thunderforest.com/cycle/{z}/{x}/{y}.png',
thunderAttr
);
// The tree containing the layers
var baseTree = [
{
label: 'OpenStreeMap',
children: [
{label: 'OSM', layer: osm, name: 'OpenStreeMap'},
{label: 'B&W', layer: osmBw, name: 'OpenStreeMap <b>B&W</b>'},
{label: 'OpenTopoMap', layer: otopomap, name: 'Topographic - OSM'},
]
},
{
label: 'Thunder',
children: [
{label: 'Cycle', layer: cycle},
{label: 'Transport', layer: transport},
]
},
];
// The map
var map = L.map('map', {
layers: [osm],
center: center,
zoom: 5
});
L.control.layers.tree(baseTree).addTo(map);
</script>
</body>
</html>

View File

@@ -0,0 +1,10 @@
<html>
<body>
<ul>
<li><a href="./basic.html">basic.html</a></li>
<li><a href="./options.html">options.html</a></li>
<li><a href="./airports.html">airports.html</a></li>
<li><a href="./basic_1.3.4.html">basic_1.3.4.html</a></li>
</ul>
</body>
</html>

View File

@@ -0,0 +1,127 @@
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>Leaflet Layers Tree Demo</title>
<link rel="stylesheet" href="https://unpkg.com/leaflet@1.4.0/dist/leaflet.css" crossorigin=""/>
<script src="https://unpkg.com/leaflet@1.4.0/dist/leaflet-src.js" crossorigin=""></script>
<style type="text/css">
html, body { width: 100%; height: 100%; margin: 0; }
#map { width: 100%; height: 100%; }
</style>
</head>
<body>
<div id="map"></div>
<link rel="stylesheet" href="../L.Control.Layers.Tree.css" crossorigin=""/>
<script src="../L.Control.Layers.Tree.js"></script>
<script type="text/javascript">
var center = [40, 0];
var osm = L.tileLayer(
'//{s}.tile.openstreetmap.org/{z}/{x}/{y}.png',
{attribution: '© OpenStreetMap contributors'}
);
var osmBw = L.tileLayer(
'http://{s}.tiles.wmflabs.org/bw-mapnik/{z}/{x}/{y}.png',
{attribution: '© OpenStreetMap contributors'}
);
var otopomap = L.tileLayer(
'//{s}.tile.opentopomap.org/{z}/{x}/{y}.png',
{attribution: '© OpenStreetMap contributors. OpenTopoMap.org'}
);
var thunderAttr = {attribution: '© OpenStreetMap contributors. Tiles courtesy of Andy Allan'}
var transport = L.tileLayer(
'//{s}.tile.thunderforest.com/transport/{z}/{x}/{y}.png',
thunderAttr
);
var cycle = L.tileLayer(
'//{s}.tile.thunderforest.com/cycle/{z}/{x}/{y}.png',
thunderAttr
);
var map = L.map('map', {
layers: [osm],
center: center,
zoom: 5
});
var baseTree = [
{
label: 'OpenStreeMap',
layer: osm,
children: [
{label: 'B&W', layer: osmBw, name: 'OpenStreeMap <b>B&W</b>'},
{label: 'OpenTopoMap', layer: otopomap, name: 'Topographic - OSM'},
]
},
{
label: 'Thunder',
children: [
{label: 'Cycle', layer: cycle},
{label: 'Transport', layer: transport},
]
},
];
var overlaysTree = {
label: 'Some cities',
children: [
{label: '<div id="onlysel">-Show only selected-</div>'},
{label: 'France', children: [
{label: 'Lyon', layer: L.marker([45.728, 4.945])},
{label: 'Paris', layer: L.marker([48.725, 2.359])},
{label: 'Toulouse', layer: L.marker([43.629, 1.364])},
]},
{label: 'Germany', children: [
{label: 'Berlin', layer: L.marker([52.559, 13.287])},
{label: 'Cologne', layer: L.marker([50.866, 7.143])},
{label: 'Hamburg', layer: L.marker([53.630, 9.988])},
{label: 'Munich', layer: L.marker([48.354, 11.786])},
]},
{label: 'Spain', children: [
{label: 'Madrid', layer: L.marker([40.472, -3.561])},
{label: 'Andalucia', children: [
{label: 'Granada', layer: L.marker([37.133, -3.636])},
{label: 'Málaga', layer: L.marker([36.674, -4.499])},
{label: 'Sevilla', layer: L.marker([37.418, -5.893])},
]},
{label: 'Bask Country', children: [
{label: '---', layer: L.layerGroup([]), radioGroup: 'bc'},
{label: 'Bilbao', layer: L.marker([43.301, -2.911]), radioGroup: 'bc'},
{label: 'San Sebastian', layer: L.marker([43.356, -1.791]), radioGroup: 'bc'},
{label: 'Vitoria', layer: L.marker([42.883, -2.724]), radioGroup: 'bc'},
]},
{label: 'Catalonia', children: [
{label: 'Barcelona', layer: L.marker([41.297, 2.078])},
{label: 'Gerona', layer: L.marker([41.901, 2.760])},
]},
]},
]
}
var lay = L.control.layers.tree(baseTree, overlaysTree,
{
namedToggle: true,
selectorBack: false,
closedSymbol: '&#8862; &#x1f5c0;',
openedSymbol: '&#8863; &#x1f5c1;',
collapseAll: 'Collapse all',
expandAll: 'Expand all',
});
lay.addTo(map).collapseTree().expandSelected().collapseTree(true);
L.DomEvent.on(L.DomUtil.get('onlysel'), 'click', function() {
lay.collapseTree(true).expandSelected(true);
});
</script>
</body>
</html>

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,46 @@
{
"name": "leaflet.control.layers.tree",
"version": "0.1.1",
"description": "Control Layers in a Tree structure",
"main": "L.Control.Layers.Tree.js",
"style": "L.Control.Layers.Tree.css",
"directories": {
"test": "test"
},
"license": "BSD-3-Clause",
"scripts": {
"lint": "eslint L.*.js test/* examples/*",
"lintfix": "eslint L.*.js test/* examples/* --fix",
"spec": "phantomjs ./node_modules/mocha-phantomjs-core/mocha-phantomjs-core.js test/index.html",
"test": "npm run lint && npm run spec"
},
"repository": {
"type": "git",
"url": "git+https://github.com/jjimenezshaw/Leaflet.Control.Layers.Tree.git"
},
"keywords": [
"Leaflet",
"map",
"geo",
"tree",
"control",
"layers"
],
"devDependencies": {
"blanket": "^1.2.3",
"chai": "~4.1.2",
"chai-leaflet": "^0.0.13",
"eslint": "^4.19.1",
"eslint-plugin-html": "^4.0.6",
"happen": "^0.3.2",
"leaflet": "^1.4.0",
"mocha": "^5.2.0",
"mocha-phantomjs-core": "^2.1.2",
"phantomjs-prebuilt": "^2.1.16"
},
"peerDependencies": {
"leaflet": "^1.1.0"
},
"author": "Javier Jimenez Shaw",
"readmeFilename": "README.md"
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 32 KiB

View File

@@ -0,0 +1,53 @@
<html>
<head>
<meta charset="utf-8">
<title>Leaflet.Control.Layers.Tree Tests</title>
<link rel="stylesheet" href="../node_modules/mocha/mocha.css" />
<link rel="stylesheet" href="../node_modules/leaflet/dist/leaflet.css" />
<link rel="stylesheet" href="../L.Control.Layers.Tree.css" />
<style>
.map, .label {
width: 400px;
height: 400px;
float: left;
}
.label {
width: 40px;
text-align: left;
font-size: 40px;
padding: 20px 30px;
}
#mocha {
clear: both;
}
</style>
</head>
<body>
<div id="maps">
<div id="mapA" class="map"></div>
</div>
<div id="mocha"></div>
<script src="../node_modules/leaflet/dist/leaflet.js"></script>
<script src="../L.Control.Layers.Tree.js" data-cover></script>
<script src="../node_modules/chai/chai.js"></script>
<script src="../node_modules/mocha/mocha.js"></script>
<script src="../node_modules/happen/happen.js"></script>
<script src="../node_modules/chai-leaflet/chai-leaflet.js"></script>
<!--script src="../node_modules/blanket/dist/mocha/blanket_mocha.js"></script-->
<script>
mocha.setup('bdd');
</script>
<script src="spec.js"></script>
<script>
mocha.globals(['L']);
(window.mochaPhantomJS || mocha).run();
</script>
</body>
</html>

View File

@@ -0,0 +1,574 @@
'use strict';
var layerA = L.tileLayer('');
var layerB = L.tileLayer('');
function baseArray1() {
return [
{label: 'Leaf one', name: 'Name Leaf one', layer: L.tileLayer('')},
{label: 'Leaf two', name: 'Name Leaf two', layer: L.tileLayer('', {idx: 'two'})},
{
label: 'Node 1',
children: [
{label: 'Leaf 11', name: 'Name Leaf 11', layer: layerA},
{label: 'Leaf 12', layer: L.tileLayer('')}
]
},
{label: 'Leaf three', name: 'Name Leaf three', layer: layerB}
];
}
function baseArray2() {
return [
{label: 'Leaf one', name: 'Name Leaf one', layer: layerA},
{label: 'Leaf two', name: 'Name Leaf two', layer: layerB},
];
}
function baseTree1() {
return {
noShow: false,
label: 'Root node',
children: baseArray1()
};
}
var markerO = L.marker([0, 0]);
var markerA = L.marker([40, 0]);
var markerB = L.marker([0, 30]);
function overlaysArray1() {
return [
{label: 'Over one', name: 'Name Over one', layer: markerO},
{label: 'Over two', name: 'Name Over two', layer: L.layerGroup([])},
{
label: 'O Node 1',
children: [
{label: 'Over 11', name: 'Name Over 11', layer: markerA},
{label: 'Over 12', layer: L.layerGroup([])}
]
},
{label: 'Over three', name: 'Name Over three', layer: markerB}
]
}
function overlaysTree1() {
return {
noShow: false,
label: 'Root O node',
children: overlaysArray1()
};
}
function overlaysArray2() {
return [
{label: 'Over A', name: 'Name Over A', layer: markerA},
{label: 'Over B', name: 'Name Over B', layer: markerB},
];
}
function isHidden(el) {
// https://stackoverflow.com/questions/19669786/check-if-element-is-visible-in-dom
return (el.offsetParent === null)
}
function checkHidden(list, value, first) {
first = first || 0;
if (!Array.isArray(value)) {
var v = value;
value = [];
for (var i = 0; i < list.length; i++) value.push(v);
}
for (var i = first; i < list.length; i++) {
isHidden(list[i]).should.be.equal(!!value[i], 'position ' + i);
}
}
describe('L.Control.Layers.Tree', function() {
chai.should();
this.timeout(5000);
var map;
beforeEach(function() {
map && map.remove();
//map = L.map(document.createElement('div'));
map = L.map('mapA');
document.body.appendChild(map._container);
});
afterEach(function() {
//map.remove();
});
describe('Functions in place', function() {
beforeEach(function() {
map.setView([0, 0], 14);
});
it('L.Control.Layers.Tree has correct func', function() {
L.control.layers.tree.should.be.a('function');
});
it('L.control.layers.tree object creation', function() {
var t = L.control.layers.tree();
t.should.be.a('object');
});
});
describe('Disabled functions', function() {
var t = L.control.layers.tree();
var methods = [t.addBaseLayer, t.addOverlay, t.removeLayer];
methods.forEach(function(method) {
(function() {
method();
}).should.throw(method.name + ' is disabled');
});
});
describe('Simple base tests', function() {
beforeEach(function() {
map.setView([0, 0], 14);
});
it('they are there', function() {
var ctl = L.control.layers.tree(baseTree1(), null,
{collapsed: false}).addTo(map);
var inputs = map._container.querySelectorAll('.leaflet-control-layers-base input');
inputs.length.should.be.equal(5);
var headers = map._container.querySelectorAll('.leaflet-control-layers-base .leaflet-layerstree-header');
headers.length.should.be.equal(7);
checkHidden(headers, false, 0);
ctl.collapseTree();
checkHidden(headers, true, 1);
});
it('they are accesible on mouseover', function() {
var ctrl = L.control.layers.tree(baseTree1()).addTo(map);
var inputs = map._container.querySelectorAll('.leaflet-control-layers-base input');
inputs.length.should.be.equal(5);
var headers = map._container.querySelectorAll('.leaflet-control-layers-base .leaflet-layerstree-header');
headers.length.should.be.equal(7);
// Nothing visible because the contrl is collapsed
checkHidden(inputs, true, 0);
checkHidden(headers, true, 0);
// mouse over the control to show it.
happen.once(ctrl._container, {type: 'mouseover'});
checkHidden(inputs, false, 0);
checkHidden(headers, false, 0);
// Hi, let it as you found it.
happen.once(ctrl._container, {type: 'mouseout'});
});
});
describe('Simple base tests with array', function() {
beforeEach(function() {
map.setView([0, 0], 14);
});
it('they are accesible on mouseover', function() {
var ctrl = L.control.layers.tree(baseArray1()).addTo(map);
var inputs = map._container.querySelectorAll('.leaflet-control-layers-base input');
inputs.length.should.be.equal(5);
var headers = map._container.querySelectorAll('.leaflet-control-layers-base .leaflet-layerstree-header');
headers.length.should.be.equal(7); // The root is hidden, but it is there
// Nothing visible because the contrl is collapsed
checkHidden(inputs, true, 0);
checkHidden(headers, true, 0);
// mouse over the control to show it.
happen.once(ctrl._container, {type: 'mouseover'});
checkHidden(inputs, false, 0);
checkHidden(headers, false, 1);
checkHidden(headers, [1, 0, 0, 0, 0, 0, 0], 0); // see, root is hidden!
// Hi, let it as you found it.
happen.once(ctrl._container, {type: 'mouseout'});
});
});
describe('Simple overlays tests', function() {
beforeEach(function() {
map.setView([0, 0], 1);
});
it('they are there', function() {
var ctl = L.control.layers.tree(null, overlaysTree1(),
{collapsed: false}).addTo(map);
var inputs = map._container.querySelectorAll('.leaflet-control-layers-overlays input');
inputs.length.should.be.equal(5);
var headers = map._container.querySelectorAll('.leaflet-control-layers-overlays .leaflet-layerstree-header');
headers.length.should.be.equal(7);
checkHidden(headers, false, 0);
ctl.collapseTree(true);
checkHidden(headers, true, 1);
});
it('they are accesible on mouseover', function() {
var ctrl = L.control.layers.tree(null, overlaysTree1()).addTo(map);
var inputs = map._container.querySelectorAll('.leaflet-control-layers-overlays input');
inputs.length.should.be.equal(5);
var headers = map._container.querySelectorAll('.leaflet-control-layers-overlays .leaflet-layerstree-header');
headers.length.should.be.equal(7);
// Nothing visible because the contrl is collapsed
checkHidden(inputs, true, 0);
checkHidden(headers, true, 0);
// mouse over the control to show it.
happen.once(ctrl._container, {type: 'mouseover'});
checkHidden(inputs, false, 0);
checkHidden(headers, false, 0);
// Hi, let it as you found it.
happen.once(ctrl._container, {type: 'mouseout'});
});
});
describe('Simple overlays array tests', function() {
beforeEach(function() {
map.setView([0, 0], 1);
});
it('they are accesible on mouseover', function() {
var ctrl = L.control.layers.tree(null, overlaysArray1()).addTo(map);
var inputs = map._container.querySelectorAll('.leaflet-control-layers-overlays input');
inputs.length.should.be.equal(5);
var headers = map._container.querySelectorAll('.leaflet-control-layers-overlays .leaflet-layerstree-header');
headers.length.should.be.equal(7);
// Nothing visible because the contrl is collapsed
checkHidden(inputs, true, 0);
checkHidden(headers, true, 0);
// mouse over the control to show it.
happen.once(ctrl._container, {type: 'mouseover'});
checkHidden(inputs, false, 0);
checkHidden(headers, false, 1);
checkHidden(headers, [1, 0, 0, 0, 0, 0, 0], 0);
// Hi, let it as you found it.
happen.once(ctrl._container, {type: 'mouseout'});
});
});
describe('Select', function() {
beforeEach(function() {
map.setView([0, 0], 14);
});
it('sel layer B and A', function() {
var ctl = L.control.layers.tree(baseTree1(), null, {collapsed: false}).addTo(map);
var headers = map._container.querySelectorAll('.leaflet-control-layers-base .leaflet-layerstree-header');
headers.length.should.be.equal(7);
happen.click(headers[6].querySelector('label'));
map._layers[L.Util.stamp(layerB)].should.be.equal(layerB);
happen.click(headers[4].querySelector('label'));
map._layers[L.Util.stamp(layerA)].should.be.equal(layerA);
});
});
describe('Labels', function() {
beforeEach(function() {
map.setView([0, 0], 1);
});
it('labels base', function() {
var ctl = L.control.layers.tree(baseTree1(), null, {collapsed: false}).addTo(map);
var headers = map._container.querySelectorAll('.leaflet-control-layers-base .leaflet-layerstree-header');
headers[3].querySelector('.leaflet-layerstree-header-name').outerText.should.be.equal('Node 1');
headers[4].querySelector('.leaflet-layerstree-header-name').outerText.should.be.equal('Leaf 11');
headers[6].querySelector('.leaflet-layerstree-header-name').outerText.should.be.equal('Leaf three');
});
});
describe('Expand and collapse', function() {
beforeEach(function() {
map.setView([0, 0], 1);
});
it('Show only selected', function() {
var ctrl = L.control.layers.tree(baseTree1(), null, {collapsed: false}).addTo(map);
map.addLayer(layerB);
var headers = map._container.querySelectorAll('.leaflet-control-layers-base .leaflet-layerstree-header');
headers.length.should.be.equal(7);
checkHidden(headers, false, 0);
ctrl.collapseTree().expandSelected(false);
checkHidden(headers, [0, 0, 0, 0, 1, 1, 0], 0);
});
it('Collapse', function() {
var ctrl = L.control.layers.tree(baseTree1(), overlaysTree1(), {collapsed: false}).addTo(map);
map.addLayer(layerB);
var headers = map._container.querySelectorAll('.leaflet-layerstree-header');
headers.length.should.be.equal(14);
checkHidden(headers, false, 0);
ctrl.collapseTree();
checkHidden(headers, [0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0], 0);
ctrl.collapseTree(true);
checkHidden(headers, [0, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1], 0);
});
it('Expand', function() {
var ctrl = L.control.layers.tree(baseTree1(), overlaysTree1(), {collapsed: false}).addTo(map);
map.addLayer(layerB);
var headers = map._container.querySelectorAll('.leaflet-layerstree-header');
headers.length.should.be.equal(14);
checkHidden(headers, false, 0);
ctrl.collapseTree().collapseTree(true);
ctrl.expandTree();
checkHidden(headers, [0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1], 0);
ctrl.expandTree(true);
checkHidden(headers, 0, 0);
});
});
describe('Names', function() {
beforeEach(function() {
map.setView([0, 0], 1);
});
it('Named Toogle', function() {
var ctrl = L.control.layers.tree(baseTree1(), overlaysTree1(), {namedToggle: true}).addTo(map);
map.addLayer(layerB);
var toggle = map._container.querySelector('.leaflet-control-layers-toggle');
toggle.innerHTML.should.be.equal('Name Leaf three');
var inputs = map._container.querySelectorAll('.leaflet-control-layers-list input');
happen.click(inputs[0]);
toggle.innerHTML.should.be.equal('Name Leaf one');
happen.click(inputs[2]);
toggle.innerHTML.should.be.equal('Name Leaf 11');
happen.click(inputs[8]);
toggle.innerHTML.should.be.equal('Name Leaf 11');
});
});
describe('Symbols', function() {
beforeEach(function() {
map.setView([0, 0], 1);
});
it('Defaults', function() {
var ctrl = L.control.layers.tree(baseTree1(), overlaysTree1(), {collapsed: false}).addTo(map);
var items = map._container.querySelectorAll('.leaflet-layerstree-closed');
items.length.should.be.equal(14);
for (var i = 0; i < items.length; i++) {
items[i].innerHTML.should.be.equal('+');
}
items = map._container.querySelectorAll('.leaflet-layerstree-opened');
items.length.should.be.equal(14);
for (var i = 0; i < items.length; i++) {
items[i].innerHTML.should.be.equal('');
}
items = map._container.querySelectorAll('.leaflet-layerstree-header-space');
items.length.should.be.equal(14);
for (var i = 0; i < items.length; i++) {
items[i].innerHTML.should.be.equal(' ');
}
});
it('Closed', function() {
var symbol = '^';
var ctrl = L.control.layers.tree(baseTree1(), overlaysTree1(), {collapsed: false, closedSymbol: symbol}).addTo(map);
map.addLayer(layerB);
var items = map._container.querySelectorAll('.leaflet-layerstree-closed');
items.length.should.be.equal(14);
for (var i = 0; i < items.length; i++) {
items[i].innerHTML.should.be.equal(symbol);
}
});
it('Opened', function() {
var symbol = 'v';
var ctrl = L.control.layers.tree(baseTree1(), overlaysTree1(), {collapsed: false, openedSymbol: symbol}).addTo(map);
var items = map._container.querySelectorAll('.leaflet-layerstree-opened');
items.length.should.be.equal(14);
for (var i = 0; i < items.length; i++) {
items[i].innerHTML.should.be.equal(symbol);
}
});
it('Space', function() {
var symbol = '_*_';
var ctrl = L.control.layers.tree(baseTree1(), overlaysTree1(), {collapsed: false, spaceSymbol: symbol}).addTo(map);
var items = map._container.querySelectorAll('.leaflet-layerstree-header-space');
items.length.should.be.equal(14);
for (var i = 0; i < items.length; i++) {
items[i].innerHTML.should.be.equal(symbol);
}
});
});
describe('Selector back', function() {
beforeEach(function() {
map.setView([0, 0], 1);
});
it('Default', function() {
var ctrl = L.control.layers.tree(baseTree1(), overlaysTree1(), {collapsed: false}).addTo(map);
var headers = map._container.querySelectorAll('.leaflet-layerstree-header');
headers.length.should.be.equal(14);
for (var h = 0; h < headers.length; h++) {
var things = [];
var keys = ['closed', 'opened', 'space', 'label']
var items = headers[h].querySelectorAll('span, label, div');
for (var i = 0; i < items.length; i++) {
keys.forEach(function(key) {
if (items[i].className.indexOf(key) > 0) {
things.push(key);
}
});
}
things[2].should.be.equal('space');
things[3].should.be.equal('label');
}
});
it('Back', function() {
var ctrl = L.control.layers.tree(baseTree1(), overlaysTree1(), {collapsed: false, selectorBack: true}).addTo(map);
var headers = map._container.querySelectorAll('.leaflet-layerstree-header');
headers.length.should.be.equal(14);
for (var h = 0; h < headers.length; h++) {
var things = [];
var keys = ['closed', 'opened', 'space', 'label']
var items = headers[h].querySelectorAll('span, label, div');
for (var i = 0; i < items.length; i++) {
keys.forEach(function(key) {
if (items[i].className.indexOf(key) > 0) {
things.push(key);
}
});
}
things[1].should.be.equal('space');
things[0].should.be.equal('label');
}
});
});
describe('Expand and collapse all', function() {
beforeEach(function() {
map.setView([0, 0], 1);
});
it('expandAll', function() {
var ctrl = L.control.layers.tree(baseTree1(), overlaysTree1(), {collapsed: false, expandAll: 'exp'}).addTo(map);
ctrl.collapseTree().collapseTree(true);
var headers = map._container.querySelectorAll('.leaflet-layerstree-header');
headers.length.should.be.equal(14);
checkHidden(headers, [0, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1], 0);
var ct = map._container.querySelectorAll('.leaflet-layerstree-expand-collapse');
ct.length.should.be.equal(2);
happen.click(ct[0]);
checkHidden(headers, [0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1], 0);
happen.click(ct[1]);
checkHidden(headers, false, 0);
});
it('collapseAll', function() {
var ctrl = L.control.layers.tree(baseTree1(), overlaysTree1(), {collapsed: false, collapseAll: 'col'}).addTo(map);
ctrl.expandTree().expandTree(true);
var headers = map._container.querySelectorAll('.leaflet-layerstree-header');
headers.length.should.be.equal(14);
checkHidden(headers, false, 0);
var ct = map._container.querySelectorAll('.leaflet-layerstree-expand-collapse');
ct.length.should.be.equal(2);
happen.click(ct[0]);
checkHidden(headers, [0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0], 0);
happen.click(ct[1]);
checkHidden(headers, [0, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1], 0);
});
it('Empties', function() {
var ctrl = L.control.layers.tree(baseTree1(), overlaysTree1(), {collapsed: false, collapseAll: '', expandAll: ''}).addTo(map);
var ct = map._container.querySelectorAll('.leaflet-layerstree-expand-collapse');
ct.length.should.be.equal(0);
});
it('All', function() {
var ctrl = L.control.layers.tree(baseTree1(), overlaysTree1(), {collapsed: false, collapseAll: 'col', expandAll: 'exp'}).addTo(map);
var ct = map._container.querySelectorAll('.leaflet-layerstree-expand-collapse');
ct.length.should.be.equal(4);
});
it('Arrays', function() {
var ctrl = L.control.layers.tree(baseArray1(), overlaysArray1(), {collapsed: false, collapseAll: 'col'}).addTo(map);
var ct = map._container.querySelectorAll('.leaflet-layerstree-expand-collapse');
var headers = map._container.querySelectorAll('.leaflet-layerstree-header');
headers.length.should.be.equal(14);
checkHidden(headers, [1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0], 0);
var ct = map._container.querySelectorAll('.leaflet-layerstree-expand-collapse');
ct.length.should.be.equal(2);
happen.click(ct[0]);
checkHidden(headers, [1, 0, 0, 0, 1, 1, 0, 1, 0, 0, 0, 0, 0, 0], 0);
happen.click(ct[1]);
checkHidden(headers, [1, 0, 0, 0, 1, 1, 0, 1, 0, 0, 0, 1, 1, 0], 0);
});
});
describe('Reset trees', function() {
beforeEach(function() {
map.setView([0, 0], 1);
});
it('case 1', function() {
var ctl = L.control.layers.tree(baseArray2(), null, {collapsed: false}).addTo(map);
map.addLayer(layerB);
map._layers[L.Util.stamp(layerB)].should.be.equal(layerB);
var headers = map._container.querySelectorAll('.leaflet-control-layers-base .leaflet-layerstree-header');
headers.length.should.be.equal(3); // including the hidden root
ctl.setBaseTree(baseTree1());
map._layers[L.Util.stamp(layerB)].should.be.equal(layerB);
headers = map._container.querySelectorAll('.leaflet-layerstree-header');
headers.length.should.be.equal(7)
happen.click(headers[4].querySelector('label'));
map._layers[L.Util.stamp(layerA)].should.be.equal(layerA);
});
it('case 2', function() {
var ctl = L.control.layers.tree(baseArray2(), overlaysTree1(), {collapsed: false}).addTo(map);
map.addLayer(layerB);
map._layers[L.Util.stamp(layerB)].should.be.equal(layerB);
var headers = map._container.querySelectorAll('.leaflet-control-layers-base .leaflet-layerstree-header');
headers.length.should.be.equal(3); // including the hidden root
ctl.setBaseTree(baseTree1());
map._layers[L.Util.stamp(layerB)].should.be.equal(layerB);
headers = map._container.querySelectorAll('.leaflet-layerstree-header');
headers.length.should.be.equal(14)
});
it('case 3', function() {
var ctl = L.control.layers.tree(baseTree1(), overlaysTree1(), {collapsed: false}).addTo(map);
map.addLayer(layerB);
map.addLayer(markerA);
map._layers[L.Util.stamp(layerB)].should.be.equal(layerB);
map._layers[L.Util.stamp(markerA)].should.be.equal(markerA);
var headers = map._container.querySelectorAll('.leaflet-layerstree-header');
headers.length.should.be.equal(14);
var inputs = map._container.querySelectorAll('.leaflet-layerstree-header input');
inputs.length.should.be.equal(10);
inputs[4].checked.should.be.true;
inputs[7].checked.should.be.true;
ctl.setBaseTree(baseArray2());
map._layers[L.Util.stamp(layerB)].should.be.equal(layerB);
map._layers[L.Util.stamp(markerA)].should.be.equal(markerA);
headers = map._container.querySelectorAll('.leaflet-layerstree-header');
headers.length.should.be.equal(10)
inputs = map._container.querySelectorAll('.leaflet-layerstree-header input');
inputs.length.should.be.equal(7);
inputs[1].checked.should.be.true;
inputs[4].checked.should.be.true;
ctl.setOverlayTree(overlaysArray2());
map._layers[L.Util.stamp(layerB)].should.be.equal(layerB);
map._layers[L.Util.stamp(markerA)].should.be.equal(markerA);
headers = map._container.querySelectorAll('.leaflet-layerstree-header');
headers.length.should.be.equal(6)
inputs = map._container.querySelectorAll('.leaflet-layerstree-header input');
inputs.length.should.be.equal(4);
inputs[1].checked.should.be.true;
inputs[2].checked.should.be.true;
});
it('case 4', function() {
var ctl = L.control.layers.tree(baseTree1(), overlaysTree1(), {collapsed: false}).addTo(map);
map.addLayer(layerB);
map.addLayer(markerO);
map._layers[L.Util.stamp(layerB)].should.be.equal(layerB);
map._layers[L.Util.stamp(markerO)].should.be.equal(markerO);
ctl.setOverlayTree(overlaysArray2());
map._layers[L.Util.stamp(layerB)].should.be.equal(layerB);
map._layers[L.Util.stamp(markerO)].should.be.equal(markerO);
var inputs = map._container.querySelectorAll('.leaflet-layerstree-header input');
inputs.length.should.be.equal(7);
inputs[5].checked.should.be.false;
inputs[6].checked.should.be.false;
});
});
});

View File

@@ -0,0 +1,112 @@
<?php
define ("GEO_EARTH_RADIUS" , 6371.0); // in km
define ("DIST_LAT_KM", acos(sin(deg2rad(0)) * sin(deg2rad(1)) + cos(deg2rad(0)) * cos(deg2rad(1)) * cos(deg2rad(0) - deg2rad(0))) * GEO_EARTH_RADIUS); // 111.19492664455 km
function getDirection($loc_long, $loc_lat, $prev_loc_long, $prev_loc_lat)
{
global $diff_str, $distLongKm;
// http://www.stern.de/noch-fragen/wie-gross-ist-der-abstand-zwischen-zwei-breitengraden-1000307782.html
// "Der Abstand zwischen zwei Breitengraden ist immer gleich und entspricht 111,32 km. Der Abstand zwischen zwei Breitengradminuten ist eine Seemeile = 1,85 km.
// Der Abstand zwischen zwei Längengraden ist am Äquator auch 111,32 km, nimmt aber umso weiter man nach Norden oder Süden kommt immer weiter ab. In Europa könnte man für grobe Berechnungen mit 70 km rechnen."
// Anmerkung: 111,32 km als Abstand zwischen zwei Breitengraden stimmt natürlich nicht ganz, da durch die Abplattung an den Polen der Abstand dort minimal kürzer ist.
// D.h. der Erdradius nimmt zu den Polen hin leicht ab. Für die Berechnung des ortsabhängigen Abstandes zwischen den Längen- und Breitengraden wird mit GEO_EARTH_RADIUS
// aus Vereinfachungsgründen der durschnittliche Erdradius genommen. Da der Abstand zwischen zwei Breitengraden nur vom Erdradius abhängig ist und daher durch GEO_EARTH_RADIUS in diesem Skript immer gleich ist,
// wird er nur einmal berechnet und fortan als Konstante verwendet
$distLongKm = acos(sin(deg2rad($loc_lat)) * sin(deg2rad($loc_lat)) + cos(deg2rad($loc_lat)) * cos(deg2rad($loc_lat)) * cos(deg2rad(0) - deg2rad(1))) * GEO_EARTH_RADIUS;
//echo "$loc_long: " . DIST_LAT_KM . ", $loc_lat: $distLongKm<br>\n";
// --- Richtungsbestimmung ---
// Achtung: Punkte liegen in zeitlich absteigender Reihenfolge vor
// Betrag in km und Richtungsbestimmung der Bewegung in der Länge: Osten oder Westen
$diff_long = ($loc_long - $prev_loc_long) * $distLongKm;
$move_long = "o";
$diff_rel_start = 0;
if ($diff_long >= 0) {
$move_long = "w";
$diff_rel_start = -360;
}
// Betrag in km und Richtungsbestimmung der Bewegung in der Breite: Norden oder Süden
$diff_lat = ($loc_lat - $prev_loc_lat) * DIST_LAT_KM;
$move_lat = "n";
if ($diff_lat >= 0) {
$move_lat = "s";
$diff_rel_start = -180;
if ($move_long == "w")
$diff_rel_start = 180;
}
$diff_str = "(" . str_replace(".", ",", sprintf("%01.3f", abs($diff_long))) . " km nach " . strtoupper($move_long) . ",<br>" . str_replace(".", ",", sprintf("%01.3f", abs($diff_lat))) . " km nach " . strtoupper($move_lat) . ")<br>";
// Bestimmung der Hauptrichtung der Bewegung in Länge oder Breite
if (abs($diff_lat) > abs($diff_long)) {
// Betrag der Bewegung in der Breite (nach Norden/Süden) ist größer als die in der Länge (nach Osten/Westen)
$direction = $move_lat;
$diff_rel = abs($diff_long) / abs($diff_lat);
if ($diff_rel >= 0.25 && $diff_rel < 0.75)
$direction .= $move_lat . $move_long;
if ($diff_rel >= 0.75)
$direction .= $move_long;
} else {
// Betrag der Bewegung in der Länge (nach Osten/Westen) ist größer als die in der Breite (nach Norden/Süden)
$direction = $move_long;
$diff_rel = abs($diff_lat) / abs($diff_long);
if ($diff_rel >= 0.25 && $diff_rel < 0.75)
$direction .= $move_lat . $move_long;
if ($diff_rel >= 0.75)
$direction = $move_lat . $direction;
$diff_rel_start = -90;
if ($diff_long >= 0) {
$diff_rel_start = 270;
}
if ($diff_lat >= 0) {
$diff_rel_start = 90;
if ($move_long == "w")
$diff_rel_start = -270;
}
}
// die Werte in $diff_rel_start sind größtenteils falsch, müssen noch korrigiert werden, bevor die Grad-Angabe ausgegeben werden kann
$diff_str = "Richtung: " /* . "<br>" . $diff_rel_start . " + " . sprintf("%01.0f", $diff_rel * 45) */ . "" . sprintf("%01.0f", abs(($diff_rel_start + $diff_rel * 45) * 10) / 10) . "° " . strtoupper($direction) . "<br>" . $diff_str;
// --- ---
// return "../images/arrow_" . $direction . ".png";
return $direction;
}
function getVelocity($loc_long, $loc_lat, $loc_time, $prev_loc_long, $prev_loc_lat, $prev_loc_time)
{
if ($loc_time == "1970-01-01 01:00:00" || $prev_loc_time == "1970-01-01 01:00:00")
return "?";
$distKm = acos(sin(deg2rad($loc_lat)) * sin(deg2rad($prev_loc_lat)) + cos(deg2rad($loc_lat)) * cos(deg2rad($prev_loc_lat)) * cos(deg2rad($prev_loc_long) - deg2rad($loc_long))) * GEO_EARTH_RADIUS;
//echo "$loc_long, $loc_lat, $loc_time, $prev_loc_long, $prev_loc_lat, $prev_loc_time, $distKm , " . (strtotime($prev_loc_time) - strtotime($loc_time)) . ", " . (($distKm / (strtotime($prev_loc_time) - strtotime($loc_time))) * 3600) . "<br>";
return round(($distKm / (strtotime($prev_loc_time) - strtotime($loc_time))) * 3600);
}
function getLocatingType($cr_gps_type) {
$cr_gps_type_text = "";
if ($cr_gps_type == 0) {
$cr_gps_type_text = "unbestimmt";
} elseif ($cr_gps_type == 1) {
$cr_gps_type_text = "LBS";
} elseif ($cr_gps_type == 2) {
$cr_gps_type_text = "GPS";
} elseif ($cr_gps_type == 3) {
$cr_gps_type_text = "Network";
} elseif ($cr_gps_type == 9) {
$cr_gps_type_text = "Ortung aus";
}
return $cr_gps_type_text;
}
function formDateTime($sqlDate) {
global $today;
return substr($sqlDate, 8, 2) . "." . substr($sqlDate, 5, 2) . "." . substr($sqlDate, 0, 4) . ", " . substr($sqlDate, 11, 8);
}
?>

View File

@@ -0,0 +1,44 @@
# Change Log
All notable changes to this project will be documented in this file.
This project adheres to [Semantic Versioning](http://semver.org/).
## [3.3.0] - 2018-03-14
- ADDED: `options.style` to use [custom map styles](https://msdn.microsoft.com/en-us/library/mt823632.aspx)
- ADDED: `AerialWithLabelsOnDemand` imagery set
- ADDED: `minNativeZoom` and `maxNativeZoom` options
- FIXED: imageryProviders error [#25](https://github.com/digidem/leaflet-bing-layer/pull/25)
## [v3.2.0] - 2017-08-09
- CHANGED: Use `https` requests
- ADDED: Additional imagery sets (`RoadOnDemand`, `CanvasLight`, `CanvasDark`, `CanvasGray`, `OrdnanceSurvey`)
## [v3.1.0] - 2016-04-29
- ADDED: Use `https` for Bing API requests.
## [v3.0.1] - 2015-12-13
- FIXED: options.BingMapsKey backwards compatability
- FIXED: options.bingMapsKey was not working for getMetaData
- FIXED: catch errors (and log to console) for jsonp
## [v3.0.0] - 2015-12-08
- FIXED: **[BREAKING]** Export factory function on `L.tileLayer.bing` not `L.TileLayer.bing`
- CHANGED: BingMapsKey is now passed on `options.bingMapsKey` (`options.BingMapsKey` will still work, but for convention this should start with a lowercase character)
- IMPROVED: Package with browserify and require dependencies
- IMPROVED: Throws error if invalid imagerySet is passed as option
- ADDED: `getMetaData` method
## v2.0.2 - 2015-12-03
Initial release
[Unreleased]: https://github.com/digidem/leaflet-bing-layer/compare/v3.2.0...HEAD
[v3.2.0]: https://github.com/digidem/leaflet-bing-layer/compare/v3.1.0...v3.2.0
[v3.1.0]: https://github.com/digidem/leaflet-bing-layer/compare/v3.0.1...v3.1.0
[v3.0.1]: https://github.com/digidem/leaflet-bing-layer/compare/v3.0.0...v3.0.1
[v3.0.0]: https://github.com/digidem/leaflet-bing-layer/compare/v2.0.2...v3.0.0

View File

@@ -0,0 +1,43 @@
# leaflet-bing-layer
Bing Maps Layer for Leaflet v1.0.0
### L.TileLayer.Bing(options|BingMapsKey)
Create a new Bing Maps Layer. Depends on [Promises](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise) which needs a polyfill for [older browsers](http://caniuse.com/#feat=promises) by adding this script to your html `<head>`:
```html
<script src="https://cdn.polyfill.io/v2/polyfill.min.js?features=Promise"></script>
```
### Parameters
| parameter | type | description |
| ----------------------------- | -------------- | ----------------------------------------------------------------------------------------------------- |
| `options` | string\|object | A valid [Bing Maps Key](https://msdn.microsoft.com/en-us/library/ff428642.aspx) or an `options` object. `options` inherits from [L.TileLayer options](http://mourner.github.io/Leaflet/reference.html#tilelayer-options) (e.g. you can use `minZoom` and `opacity` and etc) |
| `options.bingMapsKey` | string | A valid Bing Maps Key [_required_] |
| `[options.imagerySet]` | string | _optional:_ [Imagery Type](https://msdn.microsoft.com/en-us/library/ff701716.aspx) [_default=Aerial_]<br>- `Aerial` - Aerial imagery<br>- `AerialWithLabels` - Aerial imagery with a road overlay<br>- `AerialWithLabelsOnDemand` - Aerial imagery with on-demand road overlay.<br>- `CanvasDark` - A dark version of the road maps.<br>- `CanvasLight` - A lighter version of the road maps which also has some of the details such as hill shading disabled.<br>- `CanvasGray` - A grayscale version of the road maps.<br>- `Road` - Roads without additional imagery. Uses the legacy static tile service.<br>- `RoadOnDemand` - Roads without additional imagery. Uses the dynamic tile service.<br>- `OrdnanceSurvey` - Ordnance Survey imagery. This imagery is visible only for the London area.<br>**[Not supported](https://social.msdn.microsoft.com/Forums/en-US/3d80d4a6-f4c9-4926-a336-e0d545b1ef3c/is-it-possible-to-retrieve-birdseye-map-tiles-using-rest-services?forum=bingmapsservices)**: `Birdseye` and `BirdseyeWithLabels` |
| `[options.culture]` | string | _optional:_ Language for labels, [see options](https://msdn.microsoft.com/en-us/library/hh441729.aspx) [_default=en_US_] |
| `[options.style]` | string | _optional:_ Use a [custom map style](https://msdn.microsoft.com/en-us/library/mt823632.aspx) - only works with the `AerialWithLabelsOnDemand` and `RoadOnDemand` imagerySet options. |
Other options are passed through to a [Leaflet TileLayer](http://leafletjs.com/reference-1.3.0.html#tilelayer-l-tilelayer)
### Methods
| Method | Returns | Description |
| ---------- | -------------- | ------------- |
| `getMetaData(<LatLng> latlng, <Number> zoom)` | `Promise` | Get the [Bing Imagery metadata](https://msdn.microsoft.com/en-us/library/ff701712.aspx) for a specific [`LatLng`](http://leafletjs.com/reference.html#latlng) and zoom level. `latLng` or `zoom` are optional *if* the layer is attached to a map, they default to current map center and zoom. Returns a [Promise](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise) that resolves to the metadata JSON from Bing |
### Example
```js
var map = L.map('map').setView([51.505, -0.09], 13)
L.tileLayer.bing(MyBingMapsKey).addTo(map)
```
[Live Example](http://digidem.github.io/leaflet-bing-layer/) see [index.html](index.html)
### License
MIT

View File

@@ -0,0 +1,36 @@
<!DOCTYPE html>
<html>
<head>
<meta charset=utf-8 />
<meta name='viewport' content='width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no, minimal-ui' />
<title>Leaflet Bing Maps Layer</title>
<script src='http://cdn.leafletjs.com/leaflet/v1.0.0-rc.1/leaflet.js'></script>
<script src="https://cdn.polyfill.io/v2/polyfill.min.js?features=Promise"></script>
<script src="leaflet-bing-layer.js"></script>
<link href='http://cdn.leafletjs.com/leaflet/v1.0.0-rc.1/leaflet.css' rel='stylesheet' />
<style>
body {
margin: 0;
padding: 0;
}
#map {
position: absolute;
top: 0;
bottom: 0;
width: 100%;
}
</style>
</head>
<body>
<div id='map'></div>
<script>
var BING_KEY = 'AuhiCJHlGzhg93IqUH_oCpl_-ZUrIE6SPftlyGYUvr9Amx5nzA-WqGcPquyFZl4L'
var map = L.map('map').setView([51.505, -0.09], 13)
var bingLayer = L.tileLayer.bing(BING_KEY).addTo(map)
</script>
</body>
</html>

View File

@@ -0,0 +1,276 @@
var L = require('leaflet')
var fetchJsonp = require('fetch-jsonp')
var bboxIntersect = require('bbox-intersect')
/**
* Converts tile xyz coordinates to Quadkey
* @param {Number} x
* @param {Number} y
* @param {Number} z
* @return {Number} Quadkey
*/
function toQuadKey (x, y, z) {
var index = ''
for (var i = z; i > 0; i--) {
var b = 0
var mask = 1 << (i - 1)
if ((x & mask) !== 0) b++
if ((y & mask) !== 0) b += 2
index += b.toString()
}
return index
}
/**
* Converts Leaflet BBoxString to Bing BBox
* @param {String} bboxString 'southwest_lng,southwest_lat,northeast_lng,northeast_lat'
* @return {Array} [south_lat, west_lng, north_lat, east_lng]
*/
function toBingBBox (bboxString) {
var bbox = bboxString.split(',')
return [bbox[1], bbox[0], bbox[3], bbox[2]]
}
var VALID_IMAGERY_SETS = [
'Aerial',
'AerialWithLabels',
'AerialWithLabelsOnDemand',
'Road',
'RoadOnDemand',
'CanvasLight',
'CanvasDark',
'CanvasGray',
'OrdnanceSurvey'
]
var DYNAMIC_IMAGERY_SETS = [
'AerialWithLabelsOnDemand',
'RoadOnDemand'
]
/**
* Create a new Bing Maps layer.
* @param {string|object} options Either a [Bing Maps Key](https://msdn.microsoft.com/en-us/library/ff428642.aspx) or an options object
* @param {string} options.BingMapsKey A valid Bing Maps Key (required)
* @param {string} [options.imagerySet=Aerial] Type of imagery, see https://msdn.microsoft.com/en-us/library/ff701716.aspx
* @param {string} [options.culture='en-US'] Language for labels, see https://msdn.microsoft.com/en-us/library/hh441729.aspx
* @return {L.TileLayer} A Leaflet TileLayer to add to your map
*
* Create a basic map
* @example
* var map = L.map('map').setView([51.505, -0.09], 13)
* L.TileLayer.Bing(MyBingMapsKey).addTo(map)
*/
L.TileLayer.Bing = L.TileLayer.extend({
options: {
bingMapsKey: null, // Required
imagerySet: 'Aerial',
culture: 'en-US',
minZoom: 1,
minNativeZoom: 1,
maxNativeZoom: 19
},
statics: {
METADATA_URL: 'https://dev.virtualearth.net/REST/v1/Imagery/Metadata/{imagerySet}?key={bingMapsKey}&include=ImageryProviders&uriScheme=https&c={culture}',
POINT_METADATA_URL: 'https://dev.virtualearth.net/REST/v1/Imagery/Metadata/{imagerySet}/{lat},{lng}?zl={z}&key={bingMapsKey}&uriScheme=https&c={culture}'
},
initialize: function (options) {
if (typeof options === 'string') {
options = { bingMapsKey: options }
}
if (options && options.BingMapsKey) {
options.bingMapsKey = options.BingMapsKey
console.warn('use options.bingMapsKey instead of options.BingMapsKey')
}
if (!options || !options.bingMapsKey) {
throw new Error('Must supply options.BingMapsKey')
}
options = L.setOptions(this, options)
if (VALID_IMAGERY_SETS.indexOf(options.imagerySet) < 0) {
throw new Error("'" + options.imagerySet + "' is an invalid imagerySet, see https://github.com/digidem/leaflet-bing-layer#parameters")
}
if (options && options.style && DYNAMIC_IMAGERY_SETS.indexOf(options.imagerySet) < 0) {
console.warn('Dynamic styles will only work with these imagerySet choices: ' + DYNAMIC_IMAGERY_SETS.join(', '))
}
var metaDataUrl = L.Util.template(L.TileLayer.Bing.METADATA_URL, {
bingMapsKey: this.options.bingMapsKey,
imagerySet: this.options.imagerySet,
culture: this.options.culture
})
this._imageryProviders = []
this._attributions = []
// Keep a reference to the promise so we can use it later
this._fetch = fetchJsonp(metaDataUrl, {jsonpCallback: 'jsonp'})
.then(function (response) {
return response.json()
})
.then(this._metaDataOnLoad.bind(this))
.catch(console.error.bind(console))
// for https://github.com/Leaflet/Leaflet/issues/137
if (!L.Browser.android) {
this.on('tileunload', this._onTileRemove)
}
},
createTile: function (coords, done) {
var tile = document.createElement('img')
L.DomEvent.on(tile, 'load', L.bind(this._tileOnLoad, this, done, tile))
L.DomEvent.on(tile, 'error', L.bind(this._tileOnError, this, done, tile))
if (this.options.crossOrigin) {
tile.crossOrigin = ''
}
/*
Alt tag is set to empty string to keep screen readers from reading URL and for compliance reasons
http://www.w3.org/TR/WCAG20-TECHS/H67
*/
tile.alt = ''
// Don't create closure if we don't have to
if (this._url) {
tile.src = this.getTileUrl(coords)
} else {
this._fetch.then(function () {
tile.src = this.getTileUrl(coords)
}.bind(this)).catch(function (e) {
console.error(e)
done(e)
})
}
return tile
},
getTileUrl: function (coords) {
var quadkey = toQuadKey(coords.x, coords.y, coords.z)
var url = L.Util.template(this._url, {
quadkey: quadkey,
subdomain: this._getSubdomain(coords),
culture: this.options.culture
})
if (typeof this.options.style === 'string') {
url += '&st=' + this.options.style
}
return url
},
// Update the attribution control every time the map is moved
onAdd: function (map) {
map.on('moveend', this._updateAttribution, this)
L.TileLayer.prototype.onAdd.call(this, map)
this._attributions.forEach(function (attribution) {
map.attributionControl.addAttribution(attribution)
})
},
// Clean up events and remove attributions from attribution control
onRemove: function (map) {
map.off('moveend', this._updateAttribution, this)
this._attributions.forEach(function (attribution) {
map.attributionControl.removeAttribution(attribution)
})
L.TileLayer.prototype.onRemove.call(this, map)
},
/**
* Get the [Bing Imagery metadata](https://msdn.microsoft.com/en-us/library/ff701712.aspx)
* for a specific [`LatLng`](http://leafletjs.com/reference.html#latlng)
* and zoom level. If either `latlng` or `zoom` is omitted and the layer is attached
* to a map, the map center and current map zoom are used.
* @param {L.LatLng} latlng
* @param {Number} zoom
* @return {Promise} Resolves to the JSON metadata
*/
getMetaData: function (latlng, zoom) {
if (!this._map && (!latlng || !zoom)) {
return Promise.reject(new Error('If layer is not attached to map, you must provide LatLng and zoom'))
}
latlng = latlng || this._map.getCenter()
zoom = zoom || this._map.getZoom()
var PointMetaDataUrl = L.Util.template(L.TileLayer.Bing.POINT_METADATA_URL, {
bingMapsKey: this.options.bingMapsKey,
imagerySet: this.options.imagerySet,
z: zoom,
lat: latlng.lat,
lng: latlng.lng
})
return fetchJsonp(PointMetaDataUrl, {jsonpCallback: 'jsonp'})
.then(function (response) {
return response.json()
})
.catch(console.error.bind(console))
},
_metaDataOnLoad: function (metaData) {
if (metaData.statusCode !== 200) {
throw new Error('Bing Imagery Metadata error: \n' + JSON.stringify(metaData, null, ' '))
}
var resource = metaData.resourceSets[0].resources[0]
this._url = resource.imageUrl
this._imageryProviders = resource.imageryProviders || []
this.options.subdomains = resource.imageUrlSubdomains
this._updateAttribution()
return Promise.resolve()
},
/**
* Update the attribution control of the map with the provider attributions
* within the current map bounds
*/
_updateAttribution: function () {
var map = this._map
if (!map || !map.attributionControl) return
var zoom = map.getZoom()
var bbox = toBingBBox(map.getBounds().toBBoxString())
this._fetch.then(function () {
var newAttributions = this._getAttributions(bbox, zoom)
var prevAttributions = this._attributions
// Add any new provider attributions in the current area to the attribution control
newAttributions.forEach(function (attr) {
if (prevAttributions.indexOf(attr) > -1) return
map.attributionControl.addAttribution(attr)
})
// Remove any attributions that are no longer in the current area from the attribution control
prevAttributions.filter(function (attr) {
if (newAttributions.indexOf(attr) > -1) return
map.attributionControl.removeAttribution(attr)
})
this._attributions = newAttributions
}.bind(this))
},
/**
* Returns an array of attributions for given bbox and zoom
* @private
* @param {Array} bbox [west, south, east, north]
* @param {Number} zoom
* @return {Array} Array of attribution strings for each provider
*/
_getAttributions: function (bbox, zoom) {
return this._imageryProviders.reduce(function (attributions, provider) {
for (var i = 0; i < provider.coverageAreas.length; i++) {
if (bboxIntersect(bbox, provider.coverageAreas[i].bbox) &&
zoom >= provider.coverageAreas[i].zoomMin &&
zoom <= provider.coverageAreas[i].zoomMax) {
attributions.push(provider.attribution)
return attributions
}
}
return attributions
}, [])
}
})
L.tileLayer.bing = function (options) {
return new L.TileLayer.Bing(options)
}
module.exports = L.TileLayer.Bing

View File

@@ -0,0 +1,399 @@
(function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({1:[function(require,module,exports){
(function (global){
var L = (typeof window !== "undefined" ? window['L'] : typeof global !== "undefined" ? global['L'] : null)
var fetchJsonp = require('fetch-jsonp')
var bboxIntersect = require('bbox-intersect')
/**
* Converts tile xyz coordinates to Quadkey
* @param {Number} x
* @param {Number} y
* @param {Number} z
* @return {Number} Quadkey
*/
function toQuadKey (x, y, z) {
var index = ''
for (var i = z; i > 0; i--) {
var b = 0
var mask = 1 << (i - 1)
if ((x & mask) !== 0) b++
if ((y & mask) !== 0) b += 2
index += b.toString()
}
return index
}
/**
* Converts Leaflet BBoxString to Bing BBox
* @param {String} bboxString 'southwest_lng,southwest_lat,northeast_lng,northeast_lat'
* @return {Array} [south_lat, west_lng, north_lat, east_lng]
*/
function toBingBBox (bboxString) {
var bbox = bboxString.split(',')
return [bbox[1], bbox[0], bbox[3], bbox[2]]
}
var VALID_IMAGERY_SETS = [
'Aerial',
'AerialWithLabels',
'AerialWithLabelsOnDemand',
'Road',
'RoadOnDemand',
'CanvasLight',
'CanvasDark',
'CanvasGray',
'OrdnanceSurvey'
]
var DYNAMIC_IMAGERY_SETS = [
'AerialWithLabelsOnDemand',
'RoadOnDemand'
]
/**
* Create a new Bing Maps layer.
* @param {string|object} options Either a [Bing Maps Key](https://msdn.microsoft.com/en-us/library/ff428642.aspx) or an options object
* @param {string} options.BingMapsKey A valid Bing Maps Key (required)
* @param {string} [options.imagerySet=Aerial] Type of imagery, see https://msdn.microsoft.com/en-us/library/ff701716.aspx
* @param {string} [options.culture='en-US'] Language for labels, see https://msdn.microsoft.com/en-us/library/hh441729.aspx
* @return {L.TileLayer} A Leaflet TileLayer to add to your map
*
* Create a basic map
* @example
* var map = L.map('map').setView([51.505, -0.09], 13)
* L.TileLayer.Bing(MyBingMapsKey).addTo(map)
*/
L.TileLayer.Bing = L.TileLayer.extend({
options: {
bingMapsKey: null, // Required
imagerySet: 'Aerial',
culture: 'en-US',
minZoom: 1,
minNativeZoom: 1,
maxNativeZoom: 19
},
statics: {
METADATA_URL: 'https://dev.virtualearth.net/REST/v1/Imagery/Metadata/{imagerySet}?key={bingMapsKey}&include=ImageryProviders&uriScheme=https',
POINT_METADATA_URL: 'https://dev.virtualearth.net/REST/v1/Imagery/Metadata/{imagerySet}/{lat},{lng}?zl={z}&key={bingMapsKey}&uriScheme=https'
},
initialize: function (options) {
if (typeof options === 'string') {
options = { bingMapsKey: options }
}
if (options && options.BingMapsKey) {
options.bingMapsKey = options.BingMapsKey
console.warn('use options.bingMapsKey instead of options.BingMapsKey')
}
if (!options || !options.bingMapsKey) {
throw new Error('Must supply options.BingMapsKey')
}
options = L.setOptions(this, options)
if (VALID_IMAGERY_SETS.indexOf(options.imagerySet) < 0) {
throw new Error("'" + options.imagerySet + "' is an invalid imagerySet, see https://github.com/digidem/leaflet-bing-layer#parameters")
}
if (options && options.style && DYNAMIC_IMAGERY_SETS.indexOf(options.imagerySet) < 0) {
console.warn('Dynamic styles will only work with these imagerySet choices: ' + DYNAMIC_IMAGERY_SETS.join(', '))
}
var metaDataUrl = L.Util.template(L.TileLayer.Bing.METADATA_URL, {
bingMapsKey: this.options.bingMapsKey,
imagerySet: this.options.imagerySet
})
this._imageryProviders = []
this._attributions = []
// Keep a reference to the promise so we can use it later
this._fetch = fetchJsonp(metaDataUrl, {jsonpCallback: 'jsonp'})
.then(function (response) {
return response.json()
})
.then(this._metaDataOnLoad.bind(this))
.catch(console.error.bind(console))
// for https://github.com/Leaflet/Leaflet/issues/137
if (!L.Browser.android) {
this.on('tileunload', this._onTileRemove)
}
},
createTile: function (coords, done) {
var tile = document.createElement('img')
L.DomEvent.on(tile, 'load', L.bind(this._tileOnLoad, this, done, tile))
L.DomEvent.on(tile, 'error', L.bind(this._tileOnError, this, done, tile))
if (this.options.crossOrigin) {
tile.crossOrigin = ''
}
/*
Alt tag is set to empty string to keep screen readers from reading URL and for compliance reasons
http://www.w3.org/TR/WCAG20-TECHS/H67
*/
tile.alt = ''
// Don't create closure if we don't have to
if (this._url) {
tile.src = this.getTileUrl(coords)
} else {
this._fetch.then(function () {
tile.src = this.getTileUrl(coords)
}.bind(this)).catch(function (e) {
console.error(e)
done(e)
})
}
return tile
},
getTileUrl: function (coords) {
var quadkey = toQuadKey(coords.x, coords.y, coords.z)
var url = L.Util.template(this._url, {
quadkey: quadkey,
subdomain: this._getSubdomain(coords),
culture: this.options.culture
})
if (typeof this.options.style === 'string') {
url += '&st=' + this.options.style
}
return url
},
// Update the attribution control every time the map is moved
onAdd: function (map) {
map.on('moveend', this._updateAttribution, this)
L.TileLayer.prototype.onAdd.call(this, map)
this._attributions.forEach(function (attribution) {
map.attributionControl.addAttribution(attribution)
})
},
// Clean up events and remove attributions from attribution control
onRemove: function (map) {
map.off('moveend', this._updateAttribution, this)
this._attributions.forEach(function (attribution) {
map.attributionControl.removeAttribution(attribution)
})
L.TileLayer.prototype.onRemove.call(this, map)
},
/**
* Get the [Bing Imagery metadata](https://msdn.microsoft.com/en-us/library/ff701712.aspx)
* for a specific [`LatLng`](http://leafletjs.com/reference.html#latlng)
* and zoom level. If either `latlng` or `zoom` is omitted and the layer is attached
* to a map, the map center and current map zoom are used.
* @param {L.LatLng} latlng
* @param {Number} zoom
* @return {Promise} Resolves to the JSON metadata
*/
getMetaData: function (latlng, zoom) {
if (!this._map && (!latlng || !zoom)) {
return Promise.reject(new Error('If layer is not attached to map, you must provide LatLng and zoom'))
}
latlng = latlng || this._map.getCenter()
zoom = zoom || this._map.getZoom()
var PointMetaDataUrl = L.Util.template(L.TileLayer.Bing.POINT_METADATA_URL, {
bingMapsKey: this.options.bingMapsKey,
imagerySet: this.options.imagerySet,
z: zoom,
lat: latlng.lat,
lng: latlng.lng
})
return fetchJsonp(PointMetaDataUrl, {jsonpCallback: 'jsonp'})
.then(function (response) {
return response.json()
})
.catch(console.error.bind(console))
},
_metaDataOnLoad: function (metaData) {
if (metaData.statusCode !== 200) {
throw new Error('Bing Imagery Metadata error: \n' + JSON.stringify(metaData, null, ' '))
}
var resource = metaData.resourceSets[0].resources[0]
this._url = resource.imageUrl
this._imageryProviders = resource.imageryProviders || []
this.options.subdomains = resource.imageUrlSubdomains
this._updateAttribution()
return Promise.resolve()
},
/**
* Update the attribution control of the map with the provider attributions
* within the current map bounds
*/
_updateAttribution: function () {
var map = this._map
if (!map || !map.attributionControl) return
var zoom = map.getZoom()
var bbox = toBingBBox(map.getBounds().toBBoxString())
this._fetch.then(function () {
var newAttributions = this._getAttributions(bbox, zoom)
var prevAttributions = this._attributions
// Add any new provider attributions in the current area to the attribution control
newAttributions.forEach(function (attr) {
if (prevAttributions.indexOf(attr) > -1) return
map.attributionControl.addAttribution(attr)
})
// Remove any attributions that are no longer in the current area from the attribution control
prevAttributions.filter(function (attr) {
if (newAttributions.indexOf(attr) > -1) return
map.attributionControl.removeAttribution(attr)
})
this._attributions = newAttributions
}.bind(this))
},
/**
* Returns an array of attributions for given bbox and zoom
* @private
* @param {Array} bbox [west, south, east, north]
* @param {Number} zoom
* @return {Array} Array of attribution strings for each provider
*/
_getAttributions: function (bbox, zoom) {
return this._imageryProviders.reduce(function (attributions, provider) {
for (var i = 0; i < provider.coverageAreas.length; i++) {
if (bboxIntersect(bbox, provider.coverageAreas[i].bbox) &&
zoom >= provider.coverageAreas[i].zoomMin &&
zoom <= provider.coverageAreas[i].zoomMax) {
attributions.push(provider.attribution)
return attributions
}
}
return attributions
}, [])
}
})
L.tileLayer.bing = function (options) {
return new L.TileLayer.Bing(options)
}
module.exports = L.TileLayer.Bing
}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
},{"bbox-intersect":2,"fetch-jsonp":3}],2:[function(require,module,exports){
module.exports = function(bbox1, bbox2){
if(!(
bbox1[0] > bbox2[2] ||
bbox1[2] < bbox2[0] ||
bbox1[3] < bbox2[1] ||
bbox1[1] > bbox2[3]
)){
return true;
} else {
return false;
}
}
},{}],3:[function(require,module,exports){
(function (global, factory) {
if (typeof define === 'function' && define.amd) {
define(['exports', 'module'], factory);
} else if (typeof exports !== 'undefined' && typeof module !== 'undefined') {
factory(exports, module);
} else {
var mod = {
exports: {}
};
factory(mod.exports, mod);
global.fetchJsonp = mod.exports;
}
})(this, function (exports, module) {
'use strict';
var defaultOptions = {
timeout: 5000,
jsonpCallback: 'callback',
jsonpCallbackFunction: null
};
function generateCallbackFunction() {
return 'jsonp_' + Date.now() + '_' + Math.ceil(Math.random() * 100000);
}
// Known issue: Will throw 'Uncaught ReferenceError: callback_*** is not defined' error if request timeout
function clearFunction(functionName) {
// IE8 throws an exception when you try to delete a property on window
// http://stackoverflow.com/a/1824228/751089
try {
delete window[functionName];
} catch (e) {
window[functionName] = undefined;
}
}
function removeScript(scriptId) {
var script = document.getElementById(scriptId);
document.getElementsByTagName('head')[0].removeChild(script);
}
var fetchJsonp = function fetchJsonp(url) {
var options = arguments[1] === undefined ? {} : arguments[1];
var timeout = options.timeout != null ? options.timeout : defaultOptions.timeout;
var jsonpCallback = options.jsonpCallback != null ? options.jsonpCallback : defaultOptions.jsonpCallback;
var timeoutId = undefined;
return new Promise(function (resolve, reject) {
var callbackFunction = options.jsonpCallbackFunction || generateCallbackFunction();
window[callbackFunction] = function (response) {
resolve({
ok: true,
// keep consistent with fetch API
json: function json() {
return Promise.resolve(response);
}
});
if (timeoutId) clearTimeout(timeoutId);
removeScript(jsonpCallback + '_' + callbackFunction);
clearFunction(callbackFunction);
};
// Check if the user set their own params, and if not add a ? to start a list of params
url += url.indexOf('?') === -1 ? '?' : '&';
var jsonpScript = document.createElement('script');
jsonpScript.setAttribute('src', url + jsonpCallback + '=' + callbackFunction);
jsonpScript.id = jsonpCallback + '_' + callbackFunction;
document.getElementsByTagName('head')[0].appendChild(jsonpScript);
timeoutId = setTimeout(function () {
reject(new Error('JSONP request to ' + url + ' timed out'));
clearFunction(callbackFunction);
removeScript(jsonpCallback + '_' + callbackFunction);
}, timeout);
});
};
// export as global function
/*
let local;
if (typeof global !== 'undefined') {
local = global;
} else if (typeof self !== 'undefined') {
local = self;
} else {
try {
local = Function('return this')();
} catch (e) {
throw new Error('polyfill failed because global object is unavailable in this environment');
}
}
local.fetchJsonp = fetchJsonp;
*/
module.exports = fetchJsonp;
});
},{}]},{},[1]);

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,47 @@
{
"name": "leaflet-bing-layer",
"version": "3.3.0",
"description": "Bing Maps Layer for Leaflet v1.0.0",
"main": "index.js",
"browserify": {
"transform": [
"browserify-shim"
]
},
"browserify-shim": {
"leaflet": "global:L"
},
"scripts": {
"build": "browserify index.js > leaflet-bing-layer.js",
"postbuild": "uglifyjs leaflet-bing-layer.js -cm -o leaflet-bing-layer.min.js",
"preversion": "npm test && npm run build",
"lint": "standard index.js",
"start": "budo index.js:leaflet-bing-layer.js --live",
"test": "npm run lint"
},
"keywords": [
"leaflet",
"bing"
],
"author": "Gregor MacLennan",
"license": "MIT",
"repository": {
"type": "git",
"url": "https://github.com/gmaclennan/leaflet-bing-layer.git"
},
"bugs": {
"url": "https://github.com/gmaclennan/leaflet-bing-layer/issues"
},
"homepage": "https://github.com/gmaclennan/leaflet-bing-layer",
"dependencies": {
"bbox-intersect": "^0.1.1",
"browserify-shim": "^3.8.11",
"fetch-jsonp": "^1.0.0",
"leaflet": "^1.0.0-beta.2"
},
"devDependencies": {
"browserify": "^12.0.1",
"budo": "^7.0.2",
"standard": "^5.4.1"
}
}

View File

@@ -0,0 +1,31 @@
.leaflet-control-coordinates {
background-color:#D8D8D8;
background-color:rgba(255, 255, 255, 0.8);
cursor:pointer;
}
.leaflet-control-coordinates,
.leaflet-control-coordinates .uiElement input {
-webkit-border-radius:5px;
-moz-border-radius:5px;
border-radius:5px;
}
.leaflet-control-coordinates .uiElement {
margin:4px;
}
.leaflet-control-coordinates .uiElement .labelFirst {
margin-right:4px;
}
.leaflet-control-coordinates .uiHidden{
display:none;
}
.leaflet-control-coordinates .uiElement.label {
color:inherit;
font-weight: inherit;
font-size: inherit;
padding: 0;
display: inherit;
}

View File

@@ -0,0 +1,326 @@
/*
* L.Control.Coordinates is used for displaying current mouse coordinates on the map.
*/
L.Control.Coordinates = L.Control.extend({
options: {
position: 'bottomright',
//decimals used if not using DMS or labelFormatter functions
decimals: 4,
//decimalseperator used if not using DMS or labelFormatter functions
decimalSeperator: ".",
//label templates for usage if no labelFormatter function is defined
labelTemplateLat: "Lat: {y}",
labelTemplateLng: "Lng: {x}",
//label formatter functions
labelFormatterLat: undefined,
labelFormatterLng: undefined,
//switch on/off input fields on click
enableUserInput: true,
//use Degree-Minute-Second
useDMS: false,
//if true lat-lng instead of lng-lat label ordering is used
useLatLngOrder: false
},
onAdd: function(map) {
this._map = map;
var className = 'leaflet-control-coordinates',
container = this._container = L.DomUtil.create('div', className),
options = this.options;
//label containers
this._labelcontainer = L.DomUtil.create("div", "uiElement label", container);
this._label = L.DomUtil.create("span", "labelFirst", this._labelcontainer);
//input containers
this._inputcontainer = L.DomUtil.create("div", "uiElement input uiHidden", container);
var xSpan, ySpan;
if (options.useLatLngOrder) {
ySpan = L.DomUtil.create("span", "", this._inputcontainer);
this._inputY = this._createInput("inputY", this._inputcontainer);
xSpan = L.DomUtil.create("span", "", this._inputcontainer);
this._inputX = this._createInput("inputX", this._inputcontainer);
} else {
xSpan = L.DomUtil.create("span", "", this._inputcontainer);
this._inputX = this._createInput("inputX", this._inputcontainer);
ySpan = L.DomUtil.create("span", "", this._inputcontainer);
this._inputY = this._createInput("inputY", this._inputcontainer);
}
xSpan.innerHTML = options.labelTemplateLng.replace("{x}", "");
ySpan.innerHTML = options.labelTemplateLat.replace("{y}", "");
L.DomEvent.on(this._inputX, 'keyup', this._handleKeypress, this);
L.DomEvent.on(this._inputY, 'keyup', this._handleKeypress, this);
//connect to mouseevents
map.on("mousemove", this._update, this);
map.on('dragstart', this.collapse, this);
map.whenReady(this._update, this);
this._showsCoordinates = true;
//wether or not to show inputs on click
if (options.enableUserInput) {
L.DomEvent.addListener(this._container, "click", this._switchUI, this);
}
return container;
},
/**
* Creates an input HTML element in given container with given classname
*/
_createInput: function(classname, container) {
var input = L.DomUtil.create("input", classname, container);
input.type = "text";
L.DomEvent.disableClickPropagation(input);
return input;
},
_clearMarker: function() {
this._map.removeLayer(this._marker);
},
/**
* Called onkeyup of input fields
*/
_handleKeypress: function(e) {
switch (e.keyCode) {
case 27: //Esc
this.collapse();
break;
case 13: //Enter
this._handleSubmit();
this.collapse();
break;
default: //All keys
this._handleSubmit();
break;
}
},
/**
* Called on each keyup except ESC
*/
_handleSubmit: function() {
var x = L.NumberFormatter.createValidNumber(this._inputX.value, this.options.decimalSeperator);
var y = L.NumberFormatter.createValidNumber(this._inputY.value, this.options.decimalSeperator);
if (x !== undefined && y !== undefined) {
var marker = this._marker;
if (!marker) {
marker = this._marker = L.marker();
marker.on("click", this._clearMarker, this);
}
marker.setLatLng(new L.LatLng(y, x));
marker.addTo(this._map);
}
},
/**
* Shows inputs fields
*/
expand: function() {
this._showsCoordinates = false;
this._map.off("mousemove", this._update, this);
L.DomEvent.addListener(this._container, "mousemove", L.DomEvent.stop);
L.DomEvent.removeListener(this._container, "click", this._switchUI, this);
L.DomUtil.addClass(this._labelcontainer, "uiHidden");
L.DomUtil.removeClass(this._inputcontainer, "uiHidden");
},
/**
* Creates the label according to given options and formatters
*/
_createCoordinateLabel: function(ll) {
var opts = this.options,
x, y;
if (opts.labelFormatterLng) {
x = opts.labelFormatterLng(ll.lng);
} else {
x = L.Util.template(opts.labelTemplateLng, {
x: this._getNumber(ll.lng, opts)
});
}
if (opts.labelFormatterLat) {
y = opts.labelFormatterLat(ll.lat);
} else {
y = L.Util.template(opts.labelTemplateLat, {
y: this._getNumber(ll.lat, opts)
});
}
if (opts.useLatLngOrder) {
return y + " " + x;
}
return x + " " + y;
},
/**
* Returns a Number according to options (DMS or decimal)
*/
_getNumber: function(n, opts) {
var res;
if (opts.useDMS) {
res = L.NumberFormatter.toDMS(n);
} else {
res = L.NumberFormatter.round(n, opts.decimals, opts.decimalSeperator);
}
return res;
},
/**
* Shows coordinate labels after user input has ended. Also
* displays a marker with popup at the last input position.
*/
collapse: function() {
if (!this._showsCoordinates) {
this._map.on("mousemove", this._update, this);
this._showsCoordinates = true;
var opts = this.options;
L.DomEvent.addListener(this._container, "click", this._switchUI, this);
L.DomEvent.removeListener(this._container, "mousemove", L.DomEvent.stop);
L.DomUtil.addClass(this._inputcontainer, "uiHidden");
L.DomUtil.removeClass(this._labelcontainer, "uiHidden");
if (this._marker) {
var m = L.marker(),
ll = this._marker.getLatLng();
m.setLatLng(ll);
var container = L.DomUtil.create("div", "");
var label = L.DomUtil.create("div", "", container);
label.innerHTML = this._createCoordinateLabel(ll);
var close = L.DomUtil.create("a", "", container);
close.innerHTML = "Remove";
close.href = "#";
var stop = L.DomEvent.stopPropagation;
L.DomEvent
.on(close, 'click', stop)
.on(close, 'mousedown', stop)
.on(close, 'dblclick', stop)
.on(close, 'click', L.DomEvent.preventDefault)
.on(close, 'click', function() {
this._map.removeLayer(m);
}, this);
m.bindPopup(container);
m.addTo(this._map);
this._map.removeLayer(this._marker);
this._marker = null;
}
}
},
/**
* Click callback for UI
*/
_switchUI: function(evt) {
L.DomEvent.stop(evt);
L.DomEvent.stopPropagation(evt);
L.DomEvent.preventDefault(evt);
if (this._showsCoordinates) {
//show textfields
this.expand();
} else {
//show coordinates
this.collapse();
}
},
onRemove: function(map) {
map.off("mousemove", this._update, this);
},
/**
* Mousemove callback function updating labels and input elements
*/
_update: function(evt) {
var pos = evt.latlng,
opts = this.options;
if (pos) {
pos = pos.wrap();
this._currentPos = pos;
this._inputY.value = L.NumberFormatter.round(pos.lat, opts.decimals, opts.decimalSeperator);
this._inputX.value = L.NumberFormatter.round(pos.lng, opts.decimals, opts.decimalSeperator);
this._label.innerHTML = this._createCoordinateLabel(pos);
}
}
});
//construcotr registration
L.control.coordinates = function(options) {
return new L.Control.Coordinates(options);
};
//map init hook
L.Map.mergeOptions({
coordinateControl: false
});
L.Map.addInitHook(function() {
if (this.options.coordinateControl) {
this.coordinateControl = new L.Control.Coordinates();
this.addControl(this.coordinateControl);
}
});L.NumberFormatter = {
round: function (num,dec,sep) {
var res = L.Util.formatNum(num,dec)+"",
numbers=res.split(".");
if (numbers[1]) {
var d = dec-numbers[1].length;
for (; d > 0; d--) {
numbers[1]+="0";
}
res = numbers.join(sep||".");
}
return res;
},
toDMS : function (deg) {
var d = Math.floor (deg);
var minfloat = (deg-d)*60;
var m = Math.floor(minfloat);
var secfloat = (minfloat-m)*60;
var s = Math.round(secfloat);
if (s==60) {
m++;
s="00";
}
if (m==60) {
d++;
m="00";
}
if(s<10) {
s="0"+s;
}
if(m<10){
m="0"+m;
}
return ("" + d + "&deg; " + m + "' " + s + "''");
},
createValidNumber:function(num,sep){
if (num&&num.length>0){
var numbers = num.split(sep||".");
try{
var numRes=Number(numbers.join("."));
if(isNaN(numRes)){
return undefined;
}
return numRes;
}catch(e){
return undefined;
}
}
return undefined;
}
};

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 696 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 618 B

13170
html/locating/leaflet/leaflet-src.js Executable file

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

624
html/locating/leaflet/leaflet.css Executable file
View File

@@ -0,0 +1,624 @@
/* required styles */
.leaflet-pane,
.leaflet-tile,
.leaflet-marker-icon,
.leaflet-marker-shadow,
.leaflet-tile-container,
.leaflet-pane > svg,
.leaflet-pane > canvas,
.leaflet-zoom-box,
.leaflet-image-layer,
.leaflet-layer {
position: absolute;
left: 0;
top: 0;
}
.leaflet-container {
overflow: hidden;
}
.leaflet-tile,
.leaflet-marker-icon,
.leaflet-marker-shadow {
-webkit-user-select: none;
-moz-user-select: none;
user-select: none;
-webkit-user-drag: none;
}
/* Safari renders non-retina tile on retina better with this, but Chrome is worse */
.leaflet-safari .leaflet-tile {
image-rendering: -webkit-optimize-contrast;
}
/* hack that prevents hw layers "stretching" when loading new tiles */
.leaflet-safari .leaflet-tile-container {
width: 1600px;
height: 1600px;
-webkit-transform-origin: 0 0;
}
.leaflet-marker-icon,
.leaflet-marker-shadow {
display: block;
}
/* .leaflet-container svg: reset svg max-width decleration shipped in Joomla! (joomla.org) 3.x */
/* .leaflet-container img: map is broken in FF if you have max-width: 100% on tiles */
.leaflet-container .leaflet-overlay-pane svg,
.leaflet-container .leaflet-marker-pane img,
.leaflet-container .leaflet-shadow-pane img,
.leaflet-container .leaflet-tile-pane img,
.leaflet-container img.leaflet-image-layer {
max-width: none !important;
}
.leaflet-container.leaflet-touch-zoom {
-ms-touch-action: pan-x pan-y;
touch-action: pan-x pan-y;
}
.leaflet-container.leaflet-touch-drag {
-ms-touch-action: pinch-zoom;
}
.leaflet-container.leaflet-touch-drag.leaflet-touch-drag {
-ms-touch-action: none;
touch-action: none;
}
.leaflet-tile {
filter: inherit;
visibility: hidden;
}
.leaflet-tile-loaded {
visibility: inherit;
}
.leaflet-zoom-box {
width: 0;
height: 0;
-moz-box-sizing: border-box;
box-sizing: border-box;
z-index: 800;
}
/* workaround for https://bugzilla.mozilla.org/show_bug.cgi?id=888319 */
.leaflet-overlay-pane svg {
-moz-user-select: none;
}
.leaflet-pane { z-index: 400; }
.leaflet-tile-pane { z-index: 200; }
.leaflet-overlay-pane { z-index: 400; }
.leaflet-shadow-pane { z-index: 500; }
.leaflet-marker-pane { z-index: 600; }
.leaflet-tooltip-pane { z-index: 650; }
.leaflet-popup-pane { z-index: 700; }
.leaflet-map-pane canvas { z-index: 100; }
.leaflet-map-pane svg { z-index: 200; }
.leaflet-vml-shape {
width: 1px;
height: 1px;
}
.lvml {
behavior: url(#default#VML);
display: inline-block;
position: absolute;
}
/* control positioning */
.leaflet-control {
position: relative;
z-index: 800;
pointer-events: visiblePainted; /* IE 9-10 doesn't have auto */
pointer-events: auto;
}
.leaflet-top,
.leaflet-bottom {
position: absolute;
z-index: 1000;
pointer-events: none;
}
.leaflet-top {
top: 0;
}
.leaflet-right {
right: 0;
}
.leaflet-bottom {
bottom: 0;
}
.leaflet-left {
left: 0;
}
.leaflet-control {
float: left;
clear: both;
}
.leaflet-right .leaflet-control {
float: right;
}
.leaflet-top .leaflet-control {
margin-top: 10px;
}
.leaflet-bottom .leaflet-control {
margin-bottom: 10px;
}
.leaflet-left .leaflet-control {
margin-left: 10px;
}
.leaflet-right .leaflet-control {
margin-right: 10px;
}
/* zoom and fade animations */
.leaflet-fade-anim .leaflet-tile {
will-change: opacity;
}
.leaflet-fade-anim .leaflet-popup {
opacity: 0;
-webkit-transition: opacity 0.2s linear;
-moz-transition: opacity 0.2s linear;
-o-transition: opacity 0.2s linear;
transition: opacity 0.2s linear;
}
.leaflet-fade-anim .leaflet-map-pane .leaflet-popup {
opacity: 1;
}
.leaflet-zoom-animated {
-webkit-transform-origin: 0 0;
-ms-transform-origin: 0 0;
transform-origin: 0 0;
}
.leaflet-zoom-anim .leaflet-zoom-animated {
will-change: transform;
}
.leaflet-zoom-anim .leaflet-zoom-animated {
-webkit-transition: -webkit-transform 0.25s cubic-bezier(0,0,0.25,1);
-moz-transition: -moz-transform 0.25s cubic-bezier(0,0,0.25,1);
-o-transition: -o-transform 0.25s cubic-bezier(0,0,0.25,1);
transition: transform 0.25s cubic-bezier(0,0,0.25,1);
}
.leaflet-zoom-anim .leaflet-tile,
.leaflet-pan-anim .leaflet-tile {
-webkit-transition: none;
-moz-transition: none;
-o-transition: none;
transition: none;
}
.leaflet-zoom-anim .leaflet-zoom-hide {
visibility: hidden;
}
/* cursors */
.leaflet-interactive {
cursor: pointer;
}
.leaflet-grab {
cursor: -webkit-grab;
cursor: -moz-grab;
}
.leaflet-crosshair,
.leaflet-crosshair .leaflet-interactive {
cursor: crosshair;
}
.leaflet-popup-pane,
.leaflet-control {
cursor: auto;
}
.leaflet-dragging .leaflet-grab,
.leaflet-dragging .leaflet-grab .leaflet-interactive,
.leaflet-dragging .leaflet-marker-draggable {
cursor: move;
cursor: -webkit-grabbing;
cursor: -moz-grabbing;
}
/* marker & overlays interactivity */
.leaflet-marker-icon,
.leaflet-marker-shadow,
.leaflet-image-layer,
.leaflet-pane > svg path,
.leaflet-tile-container {
pointer-events: none;
}
.leaflet-marker-icon.leaflet-interactive,
.leaflet-image-layer.leaflet-interactive,
.leaflet-pane > svg path.leaflet-interactive {
pointer-events: visiblePainted; /* IE 9-10 doesn't have auto */
pointer-events: auto;
}
/* visual tweaks */
.leaflet-container {
background: #ddd;
outline: 0;
}
.leaflet-container a {
color: #0078A8;
}
.leaflet-container a.leaflet-active {
outline: 2px solid orange;
}
.leaflet-zoom-box {
border: 2px dotted #38f;
background: rgba(255,255,255,0.5);
}
/* general typography */
.leaflet-container {
font: 12px/1.5 "Helvetica Neue", Arial, Helvetica, sans-serif;
}
/* general toolbar styles */
.leaflet-bar {
box-shadow: 0 1px 5px rgba(0,0,0,0.65);
border-radius: 4px;
}
.leaflet-bar a,
.leaflet-bar a:hover {
background-color: #fff;
border-bottom: 1px solid #ccc;
width: 26px;
height: 26px;
line-height: 26px;
display: block;
text-align: center;
text-decoration: none;
color: black;
}
.leaflet-bar a,
.leaflet-control-layers-toggle {
background-position: 50% 50%;
background-repeat: no-repeat;
display: block;
}
.leaflet-bar a:hover {
background-color: #f4f4f4;
}
.leaflet-bar a:first-child {
border-top-left-radius: 4px;
border-top-right-radius: 4px;
}
.leaflet-bar a:last-child {
border-bottom-left-radius: 4px;
border-bottom-right-radius: 4px;
border-bottom: none;
}
.leaflet-bar a.leaflet-disabled {
cursor: default;
background-color: #f4f4f4;
color: #bbb;
}
.leaflet-touch .leaflet-bar a {
width: 30px;
height: 30px;
line-height: 30px;
}
/* zoom control */
.leaflet-control-zoom-in,
.leaflet-control-zoom-out {
font: bold 18px 'Lucida Console', Monaco, monospace;
text-indent: 1px;
}
.leaflet-control-zoom-out {
font-size: 20px;
}
.leaflet-touch .leaflet-control-zoom-in {
font-size: 22px;
}
.leaflet-touch .leaflet-control-zoom-out {
font-size: 24px;
}
/* layers control */
.leaflet-control-layers {
box-shadow: 0 1px 5px rgba(0,0,0,0.4);
background: #fff;
border-radius: 5px;
}
.leaflet-control-layers-toggle {
background-image: url(images/layers.png);
width: 36px;
height: 36px;
}
.leaflet-retina .leaflet-control-layers-toggle {
background-image: url(images/layers-2x.png);
background-size: 26px 26px;
}
.leaflet-touch .leaflet-control-layers-toggle {
width: 44px;
height: 44px;
}
.leaflet-control-layers .leaflet-control-layers-list,
.leaflet-control-layers-expanded .leaflet-control-layers-toggle {
display: none;
}
.leaflet-control-layers-expanded .leaflet-control-layers-list {
display: block;
position: relative;
}
.leaflet-control-layers-expanded {
padding: 6px 10px 6px 6px;
color: #333;
background: #fff;
}
.leaflet-control-layers-scrollbar {
overflow-y: scroll;
padding-right: 5px;
}
.leaflet-control-layers-selector {
margin-top: 2px;
position: relative;
top: 1px;
}
.leaflet-control-layers label {
display: block;
}
.leaflet-control-layers-separator {
height: 0;
border-top: 1px solid #ddd;
margin: 5px -10px 5px -6px;
}
/* Default icon URLs */
.leaflet-default-icon-path {
background-image: url(images/marker-icon.png);
}
/* attribution and scale controls */
.leaflet-container .leaflet-control-attribution {
background: #fff;
background: rgba(255, 255, 255, 0.7);
margin: 0;
}
.leaflet-control-attribution,
.leaflet-control-scale-line {
padding: 0 5px;
color: #333;
}
.leaflet-control-attribution a {
text-decoration: none;
}
.leaflet-control-attribution a:hover {
text-decoration: underline;
}
.leaflet-container .leaflet-control-attribution,
.leaflet-container .leaflet-control-scale {
font-size: 11px;
}
.leaflet-left .leaflet-control-scale {
margin-left: 5px;
}
.leaflet-bottom .leaflet-control-scale {
margin-bottom: 5px;
}
.leaflet-control-scale-line {
border: 2px solid #777;
border-top: none;
line-height: 1.1;
padding: 2px 5px 1px;
font-size: 11px;
white-space: nowrap;
overflow: hidden;
-moz-box-sizing: border-box;
box-sizing: border-box;
background: #fff;
background: rgba(255, 255, 255, 0.5);
}
.leaflet-control-scale-line:not(:first-child) {
border-top: 2px solid #777;
border-bottom: none;
margin-top: -2px;
}
.leaflet-control-scale-line:not(:first-child):not(:last-child) {
border-bottom: 2px solid #777;
}
.leaflet-touch .leaflet-control-attribution,
.leaflet-touch .leaflet-control-layers,
.leaflet-touch .leaflet-bar {
box-shadow: none;
}
.leaflet-touch .leaflet-control-layers,
.leaflet-touch .leaflet-bar {
border: 2px solid rgba(0,0,0,0.2);
background-clip: padding-box;
}
/* popup */
.leaflet-popup {
position: absolute;
text-align: center;
margin-bottom: 20px;
}
.leaflet-popup-content-wrapper {
padding: 1px;
text-align: left;
border-radius: 12px;
}
.leaflet-popup-content {
margin: 13px 19px;
line-height: 1.4;
}
.leaflet-popup-content p {
margin: 18px 0;
}
.leaflet-popup-tip-container {
width: 40px;
height: 20px;
position: absolute;
left: 50%;
margin-left: -20px;
overflow: hidden;
pointer-events: none;
}
.leaflet-popup-tip {
width: 17px;
height: 17px;
padding: 1px;
margin: -10px auto 0;
-webkit-transform: rotate(45deg);
-moz-transform: rotate(45deg);
-ms-transform: rotate(45deg);
-o-transform: rotate(45deg);
transform: rotate(45deg);
}
.leaflet-popup-content-wrapper,
.leaflet-popup-tip {
background: white;
color: #333;
box-shadow: 0 3px 14px rgba(0,0,0,0.4);
}
.leaflet-container a.leaflet-popup-close-button {
position: absolute;
top: 0;
right: 0;
padding: 4px 4px 0 0;
border: none;
text-align: center;
width: 18px;
height: 14px;
font: 16px/14px Tahoma, Verdana, sans-serif;
color: #c3c3c3;
text-decoration: none;
font-weight: bold;
background: transparent;
}
.leaflet-container a.leaflet-popup-close-button:hover {
color: #999;
}
.leaflet-popup-scrolled {
overflow: auto;
border-bottom: 1px solid #ddd;
border-top: 1px solid #ddd;
}
.leaflet-oldie .leaflet-popup-content-wrapper {
zoom: 1;
}
.leaflet-oldie .leaflet-popup-tip {
width: 24px;
margin: 0 auto;
-ms-filter: "progid:DXImageTransform.Microsoft.Matrix(M11=0.70710678, M12=0.70710678, M21=-0.70710678, M22=0.70710678)";
filter: progid:DXImageTransform.Microsoft.Matrix(M11=0.70710678, M12=0.70710678, M21=-0.70710678, M22=0.70710678);
}
.leaflet-oldie .leaflet-popup-tip-container {
margin-top: -1px;
}
.leaflet-oldie .leaflet-control-zoom,
.leaflet-oldie .leaflet-control-layers,
.leaflet-oldie .leaflet-popup-content-wrapper,
.leaflet-oldie .leaflet-popup-tip {
border: 1px solid #999;
}
/* div icon */
.leaflet-div-icon {
background: #fff;
border: 1px solid #666;
}
/* Tooltip */
/* Base styles for the element that has a tooltip */
.leaflet-tooltip {
position: absolute;
padding: 6px;
background-color: #fff;
border: 1px solid #fff;
border-radius: 3px;
color: #222;
white-space: nowrap;
-webkit-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
pointer-events: none;
box-shadow: 0 1px 3px rgba(0,0,0,0.4);
}
.leaflet-tooltip.leaflet-clickable {
cursor: pointer;
pointer-events: auto;
}
.leaflet-tooltip-top:before,
.leaflet-tooltip-bottom:before,
.leaflet-tooltip-left:before,
.leaflet-tooltip-right:before {
position: absolute;
pointer-events: none;
border: 6px solid transparent;
background: transparent;
content: "";
}
/* Directions */
.leaflet-tooltip-bottom {
margin-top: 6px;
}
.leaflet-tooltip-top {
margin-top: -6px;
}
.leaflet-tooltip-bottom:before,
.leaflet-tooltip-top:before {
left: 50%;
margin-left: -6px;
}
.leaflet-tooltip-top:before {
bottom: 0;
margin-bottom: -12px;
border-top-color: #fff;
}
.leaflet-tooltip-bottom:before {
top: 0;
margin-top: -12px;
margin-left: -6px;
border-bottom-color: #fff;
}
.leaflet-tooltip-left {
margin-left: -6px;
}
.leaflet-tooltip-right {
margin-left: 6px;
}
.leaflet-tooltip-left:before,
.leaflet-tooltip-right:before {
top: 50%;
margin-top: -6px;
}
.leaflet-tooltip-left:before {
right: 0;
margin-right: -12px;
border-left-color: #fff;
}
.leaflet-tooltip-right:before {
left: 0;
margin-left: -12px;
border-right-color: #fff;
}

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,93 @@
<?php
/*=======================================================================
*
* locating.php
*
* Autor: Marc Vollmann
*
=======================================================================*/
include_once ("../include/mcglobal.inc.php");
include_once ("../include/auth.inc.php");
include_once ("../include/ranking.inc.php");
// Check HTTP-Parameters
getSecHttpVars("1",array("f_act", "customerId", "cscIdRoot", "cscIdActual", "f_cr_sid", "useRemoteDB"));
// Check for authentication access and granted rights
$usrAccessArray["hq"] = "1";
authCheckForAccess($hq_id, $usr_id, $emp_id, "1", $customerId, $cscIdRoot, $cscIdActual);
authCheckEmployeeRights($emp_id, "4", "1");
// ******************************************************
// Very special treatment for access to remote database
include_once ("../include/bwv.inc.php");
$remoteDBisActive = false;
if (BWV2_checkEmpRemoteDBAccess($useRemoteDB, $emp_id)) :
$remoteDBisActive = BWV2_setRemoteDBAccessParameter();
endif;
// ******************************************************
// *********************************
// * Search MSISDN from courier-id *
// *********************************
// Get courier-id from the courier-sid (e.g. SIDs: 1013, 1019, etc.)
$cr_id = getFieldValueFromId("courier","cr_sid",$f_cr_sid,"cr_id");
$msisdn = getFieldValueFromId("courier","cr_id",$cr_id,"cr_mobile_pda");
// Remove blanks in MSISDN and check beginning with "49"
// (IMPORTANT: No check for other chars because checked in javascript !!!)
$msisdn = ereg_replace (" ", "", $msisdn);
$msisdn = str_replace("+", "", $msisdn);
if (!ereg("^" . COUNTRY_FON_PREFIX, $msisdn)) :
if (ereg("^0", $msisdn)) :
$msisdn = substr($msisdn, 1);
endif;
$msisdn = COUNTRY_FON_PREFIX . $msisdn;
endif;
// $locatingURL = "../locating/locating_tmobile.php"; // D1
// if (substr($msisdn, 0, 4) == "0173" || substr($msisdn, 0, 5) == "49173") :
// $locatingURL = "../locating/locating_D2.php"; // D2
// endif;
$locatingURL = "../locating/locating_D2.php"; // D2
?>
<html lang="de">
<head>
<title>ORTUNGSWRAPPER</title>
<link rel="stylesheet" type="text/css" href="../css/phoenix.css">
<script type="text/javascript">
<!--
function doSubmit() {
document.forms[0].submit();
};
-->
</script>
</head>
<body onLoad="javascript:doSubmit();">
<form action="<?php echo $locatingURL ?>" method="post">
<input type="hidden" name="f_act" value="<?php echo $f_act ?>">
<input type="hidden" name="customerId" value="<?php echo $customerId ?>">
<input type="hidden" name="cscIdRoot" value="<?php echo $cscIdRoot ?>">
<input type="hidden" name="cscIdActual" value="<?php echo $cscIdActual ?>">
<input type="hidden" name="f_cr_sid" value="<?php echo $f_cr_sid ?>">
<input type="hidden" name="useRemoteDB" value="<?php echo $useRemoteDB ?>">
</form>
</body>
</html>

View File

@@ -0,0 +1,659 @@
<?php
/*=======================================================================
*
* locating_D2.php
*
* Autor: Marc Vollmann
*
=======================================================================*/
include_once ("../include/mcglobal.inc.php");
include_once ("../include/auth.inc.php");
include_once ("../include/ranking.inc.php");
// Check HTTP-Parameters
getSecHttpVars("1",array("f_act", "customerId", "cscIdRoot", "cscIdActual", "f_cr_sid", "useRemoteDB"));
$locatingURL = "../locating/locating_D2.php";
// Check for authentication access and granted rights
$usrAccessArray["hq"] = "1";
authCheckForAccess($hq_id, $usr_id, $emp_id, "1", $customerId, $cscIdRoot, $cscIdActual);
authCheckEmployeeRights($emp_id, "4", "1");
// ******************************************************
// Very special treatment for access to remote database
include_once ("../include/bwv.inc.php");
echo $useRemoteDB . "<br>";
$remoteDBisActive = false;
if (BWV2_checkEmpRemoteDBAccess($useRemoteDB, $emp_id)) :
$remoteDBisActive = BWV2_setRemoteDBAccessParameter();
endif;
// ******************************************************
/*
FLOW:
- General definitions
- Get courier-id from http-request
- Search MSISDN from courier-id
- Generate request
- Send request
- Parse response
- Search x,y-coordinates in cells to be valid
- Compute longitude and latitude (transformation)
- Get zipcode from coordinates
- Update zipcode of the courier
- Write to log-file|log-db (employee, datetime, courier-id, msisdn, [zipcode, x_y_of_cell])
- Output zipcode
*/
// ***********************
// * General definitions *
// ***********************
// Proxy und Port fuer HTTPS
$proxy = "";
// $port = ":9883"; // D2 LBS-Testsystem
$port = ":705"; // D2 LBS-Live
$constPort = getParameterValue("0", "LOCATING_LBS_PORT", "0");
if ($constPort != "") : $port = $constPort; endif;
// $server = "213.148.156.83"; // D2 LBS-Testsystem
$server = "139.7.25.166"; // D2 LBS-Live
$constServer = getParameterValue("0", "LOCATING_LBS_SERVER", "0");
if ($constServer != "") : $server = $constServer; endif;
// Access to a special remote file
// $file = "ats/receiver"; // D2 LBS-Testsystem
$file = "LocationQueryService"; // D2 LBS-Live
// Request id
// $requestID = "1";
$requestID = rand(1,30000);
// User and password
$vaspID = "mi2ju GmbH"; // D2 Live
$constVaspID = getParameterValue("0", "LOCATING_LBS_VASP_ID", "0");
if ($constVaspID != "") : $vaspID = $constVaspID; endif;
$password = "mi2ju03#"; // D2 Live
$constPassword = getParameterValue("0", "LOCATING_LBS_PASSWORD", "0");
if ($constPassword != "") : $password = $constPassword; endif;
// Service ID
// $serviceId = "mi2juTest"; // D2 Testsystem
$serviceId = "mi2ju"; // D2 Live
$constServiceId = getParameterValue("0", "LOCATING_LBS_SERVICE_ID", "0");
if ($constServiceId != "") : $serviceId = $constServiceId; endif;
// Maximum of age of locating info
$maxAgeOfLocatingInfoInSeconds = "300";
// Minimum of the granularity
$minOfGranularityInMeter = "99999";
// Client Certificate and Private Key
$clientcertkey = '-cert cacert.pem -key privkey.pem';
// Path to openssl
$openssl = 'openssl';
// Port of openssl
$opensslPort = "9213";
// Only for output
$status_message = "";
// Logging enabled
$loggingEnabled = TRUE;
$logFile = "../log/COM_LOG";
// Echo enabled
$echoEnabled = FALSE;
// *************
// * Functions *
// *************
function writeLocatingLog($file, $value) {
global $loggingEnabled;
if ($loggingEnabled) :
writeToFile($file, $value);
endif;
}
function connectD2($completeReq) {
global $server, $port;
$response = "";
$errno = "";
$errstr = "";
$fp = fsockopen ($server, substr($port, 1), $errno, $errstr, 10);
if (!$fp) {
$response = "$errstr ($errno)<br>\n";
} else {
fputs ($fp, $completeReq);
if (fflush($fp)) :
// Read header
$httpHeader = "";
$httpBodyLength = 0;
if (!feof($fp)) :
$line = trim(fgets ($fp,1024));
$httpHeader .= trim($line);
while (!feof($fp) && $line != "") {
$line = trim(fgets ($fp,1024));
$httpHeader .= $line;
if (!(strpos($line, "Content-Length: ") === FALSE)) :
$httpBodyLength = trim(substr($line, 16));
endif;
}
endif;
// writeLocatingLog($logFile, "::: " . $httpHeader . "\r\n");
// writeLocatingLog($logFile, "::: " . $httpBodyLength . "\r\n");
/*
// while (!feof($fp) && $line != "</SLIA>") {
while (!feof($fp) && strlen($response) < ($httpBodyLength - 7)) {
$line = trim(fgets ($fp,1024));
$response .= $line;
}
*/
$count = 0;
while (!feof($fp) && $count < $httpBodyLength) {
$line = trim(fgets ($fp,2));
$response .= $line;
$count++;
}
// writeLocatingLog($logFile, ":# Loops: " . $count . "\r\n");
else :
$response = "ERR: " . $errno . " " . $errstr;
endif;
fclose ($fp);
}
return $response;
}
// *********************************
// * Search MSISDN from courier-id *
// *********************************
// Get courier-id from the courier-sid (e.g. SIDs: 1013, 1019, etc.)
$cr_id = getFieldValueFromId("courier","cr_sid",$f_cr_sid,"cr_id");
$msisdn = getFieldValueFromId("courier","cr_id",$cr_id,"cr_mobile_pda");
$imei = getFieldValueFromId("courier","cr_id",$cr_id,"cr_imei");
$serialno = getFieldValueFromId("courier","cr_id",$cr_id,"cr_serialno");
// Remove blanks in MSISDN and check beginning with "49"
// (IMPORTANT: No check for other chars because checked in javascript !!!)
$msisdn = ereg_replace (" ", "", $msisdn);
$msisdn = str_replace("+", "", $msisdn);
if (!ereg("^" . COUNTRY_FON_PREFIX, $msisdn)) :
if (ereg("^0", $msisdn)) :
$msisdn = substr($msisdn, 1);
endif;
$msisdn = COUNTRY_FON_PREFIX . $msisdn;
endif;
// Check necessity of new locating process
$locatingStateArray = checkLocatingState($cr_id);
//echo $locatingStateArray[0] . "\n";
// ********************************************************
// * Generate request if broker service will be contacted *
// ********************************************************
/*
if ($locatingStateArray[0] == "1") :
writeLocatingLog($logFile, json_encode($locatingStateArray) . "\r\n");
// Define header request
$requestheaderOrg = "POST /" . $file . " HTTP/1.1\r\n" .
"Host: $server$port\r\n" .
"Content-Type: application/x-www-form-urlencoded\r\n" .
"Content-Length: LENGTH\r\n\r\n";
// Connection request
$requestContext = "<?xml version='1.0'?><!DOCTYPE HDR SYSTEM 'MLEP_HDR.DTD'><HDR ver='1.0'><CLIENT><ID>$vaspID</ID><PWD>$password</PWD><SERVICEID>$serviceId</SERVICEID><SERVICE_TYPE service_type_type='PASSIVE'/></CLIENT></HDR>";
$requestMethod = "SLIR";
$requestBody = "<?xml version='1.0'?><!DOCTYPE SLIR SYSTEM 'MLEP_SLIR.DTD'><SLIR ver='1.0'><MSIDS><MSID>" . $msisdn . "</MSID></MSIDS></SLIR>";
$requestContext = urlencode($requestContext);
$requestBody = urlencode($requestBody);
// Merge "Context", "Method" and "Body"
$requestContext = "Context=" . $requestContext . "&Method=" . $requestMethod . "&Body=" . $requestBody;
$laenge = strlen($requestContext);
$requestheader = $requestheaderOrg;
$requestheader = str_replace ("LENGTH", $laenge, $requestheader);
if ($echoEnabled) : echo $requestheader . $requestContext . "\n\n\n"; endif;
writeLocatingLog($logFile, $requestheader . $requestContext . "\r\n");
$currentTime = getDateTime("0");
writeLocatingLog($logFile, "Time begin: " . $currentTime . "\r\n");
// $response = connectD2($requestheader.$requestContext."\r\n");
$response = "dummy";
$currentTime = getDateTime("0");
writeLocatingLog($logFile, "Time end: " . $currentTime . "\r\n");
if ($echoEnabled) : echo $response . "\n\n\n"; endif;
writeLocatingLog($logFile, $response . "\r\n");
else :
*/
$longitude = $locatingStateArray[1];
$latitude = $locatingStateArray[2];
$gpsTime = $locatingStateArray[4];
// Generate a faked response to be parsed correctly
$response = "";
$response .= "<POINT>";
$response .= " <LL_POINT>";
$response .= " <LAT>" . $locatingStateArray[2] . "</LAT>";
$response .= " <LONG>" . $locatingStateArray[1] . "</LONG>";
$response .= " </LL_POINT>";
$response .= "</POINT>";
$response .= "<RAD>XXXX</RAD>";
//endif;
// Evaluation of the response
if ($response == "") :
// Error occurred, response is empty ...
$status_message = "Es wurde keine Antwort geliefert!";
else :
if ((FALSE && !(strpos($response, "<POSERR>") === FALSE)) || ($longitude == 0 && $latitude == 0)) :
// Error occurred, ...
$status_message = "Die Nummer konnte nicht geortet werden!";
else :
if ((strpos($response, "<POINT>") === FALSE)) :
$status_message = "Die Lokalisierung war nicht möglich!";
else :
// GET LOCATING INFOS OF THE RESPONSE
// Get latitude
/*
$beginPos = strpos($response, "<LAT>") + 5;
$endPos = strpos($response, "</LAT>");
$latitude = substr($response, $beginPos, $endPos - $beginPos);
$latitude = substr($latitude, 0, -4) . "." . substr($latitude, -4); // Insert char "."
*/
// Get longitude
/*
$beginPos = strpos($response, "<LONG>") + 6;
$endPos = strpos($response, "</LONG>");
$longitude = substr($response, $beginPos, $endPos - $beginPos);
$longitude = substr($longitude, 0, -4) . "." . substr($longitude, -4); // Insert char "."
*/
/*
<SLIA ver="1.0">
<POS>
<MSID>491736281211</MSID>
<PD>
<TIME>
<LOCAL_TIME>20070424163805</LOCAL_TIME>
<GMT_OFF>+0200</GMT_OFF>
</TIME><SHAPE>
<CIRCLE>
<POINT>
<LL_POINT>
<LAT>523011.999</LAT>
<LONG>132424.001</LONG>
</LL_POINT>
</POINT>
<RAD>293</RAD>
</CIRCLE>
</SHAPE>
</PD>
</POS>
<GMT_OFF>+0200</GMT_OFF>
<RESULT resid="0">OK</RESULT>
<SESSIONID>AAADswAAARIkPfYcZByzGh+MVoO8Dt2Uevwx</SESSIONID>
</SLIA>
*/
/*
// GET LOCATING INFOS OF THE RESPONSE
// If no request has to be send to the server the current longitude and latitude are defined
if ($locatingStateArray[0] == "1") :
// Get latitude from connection request
$beginPos = strpos($response, "<LAT>") + 5;
$endPos = strpos($response, "</LAT>");
$latitudeRaw = substr($response, $beginPos, $endPos - $beginPos);
if ($echoEnabled) : echo "CoordPair: " . $coordPair . "<br>"; endif;
// Get longitude from connection request
$beginPos = strpos($response, "<LONG>") + 6;
$endPos = strpos($response, "</LONG>");
$longitudeRaw = substr($response, $beginPos, $endPos - $beginPos);
if ($echoEnabled) : echo "CoordPair: " . $coordPair . "<br>"; endif;
// Get radius from connection request
$beginPos = strpos($response, "<RAD>") + 5;
$endPos = strpos($response, "</RAD>");
$radius = substr($response, $beginPos, $endPos - $beginPos);
if ($echoEnabled) : echo "CoordPair: " . $coordPair . "<br>"; endif;
// Transform data
// Example: $coordPair = "555555,133333"
// $coordPairArray[0] = "555555" | $coordPairArray[0] = "133333"
// $x_coord_array[0] = "55" (Stellen 0 und 1) | $x_coord_array[1] = "55" (Stellen 2 und 3) | $x_coord_array[2] = "55" (Stellen 4 und 5)
// $y_coord_array[0] = "13" (Stellen 0 und 1) | $y_coord_array[1] = "33" (Stellen 2 und 3) | $y_coord_array[2] = "33" (Stellen 4 und 5)
$latitudeRawArray = array();
$tmpPos = strpos($latitudeRaw, ".");
if (!($tmpPos === FALSE)) :
$latitudeRawArray[0] = substr($latitudeRaw, 0, $tmpPos);
$latitudeRawArray[1] = substr($latitudeRaw, $tmpPos);
else :
$latitudeRawArray[0] = $latitudeRaw;
$latitudeRawArray[1] = "0";
endif;
$longitudeRawArray = array();
$tmpPos = strpos($longitudeRaw, ".");
if (!($tmpPos === FALSE)) :
$longitudeRawArray[0] = substr($longitudeRaw, 0, $tmpPos);
$longitudeRawArray[1] = substr($longitudeRaw, $tmpPos);
else :
$longitudeRawArray[0] = $longitudeRaw;
$longitudeRawArray[1] = "0";
endif;
$latitudeRawArray[0] = pad($latitudeRawArray[0], 6, "0"); // if less than 6 chars
$longitudeRawArray[0] = pad($longitudeRawArray[0], 6, "0"); // if less than 6 chars
if ($latitudeRawArray[1] == "") : $latitudeRawArray[1] = "0"; endif;
if ($longitudeRawArray[1] == "") : $longitudeRawArray[1] = "0"; endif;
$x_coord_array[0] = substr($latitudeRawArray[0], 0, 2);
$x_coord_array[1] = substr($latitudeRawArray[0], 2, 2);
$x_coord_array[2] = substr($latitudeRawArray[0], 4);
$y_coord_array[0] = substr($longitudeRawArray[0], 0, 2);
$y_coord_array[1] = substr($longitudeRawArray[0], 2, 2);
$y_coord_array[2] = substr($longitudeRawArray[0], 4);
// ***************************************************
// * Compute longitude and latitude (transformation) *
// ***************************************************
$longitude = $y_coord_array[0] + $y_coord_array[1] / 60 + ($y_coord_array[2] + $longitudeRawArray[1]) / 3600;
$latitude = $x_coord_array[0] + $x_coord_array[1] / 60 + ($x_coord_array[2] + $latitudeRawArray[1]) / 3600;
writeLocatingLog($logFile, "-->" . $latitude . " " . $longitude . "<-- \r\n");
endif;
*/
// ********************************
// * Get zipcode from coordinates *
// ********************************
$constLocatingMode = LOCATING_MODE;
if ($constLocatingMode == "0") :
$zipcode = findZipcodeArea($longitude, $latitude);
if (trim($zipcode) == "") :
$constLocatingMode = "1";
endif;
endif;
if ($constLocatingMode == "1") :
// Get nearest coordinates
$sqlquery = "SELECT srvp.srvp_id, srvp.srvp_plz, srvp.srvp_latitude, srvp.srvp_longitude, "
. "SQRT(POW(ABS(srvp.srvp_latitude - $latitude),2) + POW(ABS(srvp.srvp_longitude - $longitude),2)) AS nb"
. " FROM serviceplz AS srvp"
. " ORDER BY nb"
. " LIMIT 0,1";
$result = $db->query($sqlquery);
if (DB::isError($result)) die ("$PHP_SELF: " . $result->getMessage());
// all defined db-fields an titles shall become content of the following arrays
while ($row = $result->fetch_assoc()):
$f_srvp_plz = $row["srvp_plz"]; // Zipcode to be displayed
endwhile;
$result->free();
$zipcode = $f_srvp_plz;
endif;
$status_message = "<b>Letzte erfolgreiche Ortung: " . $zipcode . "</b></br></br>"
. "(" . $longitude . " / " . $latitude . " um " . formatOutput($gpsTime,"datetime","4") . " " . formatOutput($gpsTime,"datetime","10") . ")</br></br>"
. "<a href=\"../locating/map_courier.php?cr_sid=" . $f_cr_sid . "\" target=\"_blank\">[Kartendarstellung]</a><br><br></br>";
// *********************************
// * Update zipcode of the courier *
// *********************************
$updateRankingTime = TRUE;
// Get current zipcode of the courier out of the table "courier" (cr_locationzipcode) to compare with locating zipcode
$crLocationZipcode = getFieldValueFromId("courier","cr_id",$cr_id,"cr_locationzipcode");
$status_message .= "<b>(Freimeldung des Kuriers: " . $crLocationZipcode . ")</b><br><br>";
if ($zipcode != "" && $crLocationZipcode != "" && is_numeric($crLocationZipcode)) :
// Check current zipcode with locating zipcode
if ($zipcode == $crLocationZipcode) :
$updateRankingTime = FALSE;
else :
// Check locating zipcode is in neighbourhood
// If true then ok => do not update ranking time
// Get the general mediation mode for the headquarter
$mediationMode = MODE_INTERMEDIATION;
if ($mediationMode == "") :
$mediationMode = getFieldValueFromId("headquarters", "hq_id", "$hq_id", "hq_invmode");
endif;
// Get all neighbours for the current zipcode(area)
if ($mediationMode == "1") :
$zicodeArray = getCourierByRanking($crLocationZipcode, "0000010000", "", "");
$zicodeArray = $zicodeArray[5];
else :
$areaIdArray = getCourierByRanking($crLocationZipcode, "0000010000", "", "");
$areaIdArray = $areaIdArray[5];
// Add ID of the main mediation area
$srvpIdZipcode = getFieldValueFromId("serviceplz","srvp_plz",$crLocationZipcode,"srvp_id");
// $srvpaIdMain = getFieldValueFromId("serviceplzareamapping","srvp_id",$srvpIdZipcode,"srvpa_id");
$srvpaIdMain = $db->getOne("SELECT srvpam.srvpa_id FROM serviceplzarea AS srvpa, serviceplzareamapping AS srvpam" .
" WHERE srvpam.srvp_id = '" . $srvpIdZipcode . "' AND srvpa.srvpa_id = srvpam.srvpa_id AND srvpa.hq_id = '" . $hq_id . "'");
if ($areaIdArray == "") : $areaIdArray = array(); endif;
array_push($areaIdArray, $srvpaIdMain);
$areaIdArrayLen = count($areaIdArray);
$outputOfAllValidMainZipcodes = "<b>GÜLTIGE BEREICHE:</b><br>";
$outputOfAllValidMainZipcodes .= "_________________ <br><br>";
$outputOfAllValidMainZipcodes .= "<b>Hauptbereich:</b><br>";
$outputOfAllValidNeighbourZipcodes = "";
$zicodeArray = array();
for ($i = 0; $i < $areaIdArrayLen; $i++) :
if ($i < $areaIdArrayLen - 1) :
$outputOfAllValidNeighbourZipcodes .= "<b>Nachbarbereich " . ($i + 1) . "</b><br>";
endif;
$sqlquery = "SELECT srvp.srvp_plz"
. " FROM serviceplzareamapping AS srvpam, serviceplz AS srvp"
. " WHERE srvpam.srvp_id = srvp.srvp_id AND srvpam.srvpa_id = '" . $areaIdArray[$i] . "'";
$result = $db->query($sqlquery);
if (DB::isError($result)) die ("$PHP_SELF: " . $result->getMessage());
while ($row = $result->fetch_assoc()):
$zicodeArray[] = $row[srvp_plz];
if ($i < $areaIdArrayLen - 1) :
$outputOfAllValidNeighbourZipcodes .= $row[srvp_plz] . "<br>";
else :
$outputOfAllValidMainZipcodes .= $row[srvp_plz] . "<br>";
endif;
endwhile;
$result->free();
if ($i < $areaIdArrayLen - 1) :
$outputOfAllValidNeighbourZipcodes .= "----------------- <br><br>";
else :
$outputOfAllValidMainZipcodes .= "----------------- <br><br>";
endif;
endfor;
$outputOfAllValidZipcodes = $outputOfAllValidMainZipcodes . $outputOfAllValidNeighbourZipcodes;
endif;
$zicodeArrayLen = count($zicodeArray);
for ($i = 0; $i < $zicodeArrayLen; $i++) :
if ($zipcode == $zicodeArray[$i]) :
$updateRankingTime = FALSE;
endif;
endfor;
endif;
$currentTime = getDateTime("0");
if ($updateRankingTime) :
if (locatingIsPlausible($cr_id, $locatingStateArray[1], $locatingStateArray[2], $locatingStateArray[3], $locatingStateArray[4], $locatingStateArray[5]) && $locatingStateArray[0] == "0") :
updateStmt("courier", "cr_id", $cr_id, array("cr_locationzipcode", $zipcode, "cr_availabletime", $currentTime));
$status_message .= "Die Rankingposition ging verloren! <br><br>";
else:
$status_message .= "Die Rankingposition bleibt erhalten! <br><br>";
$updateRankingTime = false; // wg. Logging s.u.
endif;
else :
// updateStmt("courier", "cr_id", $cr_id, array("cr_locationzipcode", $zipcode));
$status_message .= "Die Rankingposition bleibt erhalten! <br><br>";
endif;
if ($locatingStateArray[0] == "1"):
$status_message .= "<span style=\"color:red\"><b>Diese Positionsangabe ist veraltet, es sind keine aktuellen Ortungsdaten verf&uuml;gbar.<b></span><br><br>";
endif;
else :
$currentTime = getDateTime("0");
// 07.06.2024 CA: Kein Update wenn $locatingStateArray[0] != "0"
if ($zipcode != "" && $locatingStateArray[0] == "0") :
updateStmt("courier", "cr_id", $cr_id, array("cr_locationzipcode", $zipcode, "cr_availabletime", $currentTime));
endif;
endif;
// Update current position to courier with timestamp
/*
if ($longitude != "" && $latitude != "" &&
substr($longitude , 0, 1) != "0" && substr($latitude , 0, 1) != "0" &&
is_numeric($longitude) && is_numeric($latitude)) :
// updateStmt("courier", "cr_id", $cr_id, array("cr_gps_long", $longitude, "cr_gps_lat", $latitude, "cr_gps_time", $currentTime));
// Changed because of "cr_modify" has not to be changed by update and "cr_gps_type" has to be set!
if ($locatingStateArray[0] == "1") :
$sqlStmt = "UPDATE courier SET cr_gps_long = '" . $longitude . "', cr_gps_lat = '" . $latitude . "', cr_gps_time = '" . $currentTime . "', cr_gps_type = '1', cr_modify = cr_modify WHERE cr_id = '" . $cr_id . "'";
$res = $db->query($sqlStmt);
if (DB::isError($res)) die ("$PHP_SELF: <br>$sqlStmt<br>" . $res->getMessage());
endif;
endif;
*/
// ***********
// * LOGGING *
// ***********
// Get usr_id of the current employee (session)
$currentSessionUsrId = getFieldValueFromId("employee", "emp_id", $emp_id, "usr_id");
// Loose Ranking yes/no
$looseRanking = "NO";
// 07.06.2024 CA: Kein "Ranking verloren" wen alte PLZ leer war!"
if ($updateRankingTime && $crLocationZipcode != "" && is_numeric($crLocationZipcode)) : $looseRanking = "YES"; endif;
// Write logdata into log database
writeToLogDB("27",$hq_id,"0",$currentSessionUsrId,$cr_id,$f_cr_sid,"","LONG=".$longitude."|LAT=".$latitude."|ZIP_REAL=".$zipcode."|ZIP_FREE=".$crLocationZipcode."|NO=".$msisdn."|LRANK=".$looseRanking."|LMODE=".$constLocatingMode."|LOCOLD=".($locatingStateArray[0] == "0" ? "NO" : "YES"));
// ********************
// * Close connection *
// ********************
$requestID++;
$requestConnectionRelease = "<MESSAGE_TYPE=3><REQUEST_ID=" . $requestID . "><SESSION_HANDLE=" . $sessionHandle . ">";
$laenge = strlen($requestConnectionRelease);
$requestheader = $requestheaderOrg;
$requestheader = str_replace ("LENGTH", $laenge, $requestheader);
if ($echoEnabled) : echo $requestheader.$requestConnectionRelease . "<br><br><br>"; endif;
// Connect Release
// $response = connectD2($requestheader.$requestConnectionRelease."\r\n");
endif;
endif;
endif;
?>
<html lang="de">
<head>
<title>ORTUNG</title>
<link rel="stylesheet" type="text/css" href="../css/phoenix.css">
</head>
<body onLoad="this.moveTo((screen.width * 0.5)-(document.body.offsetWidth * 0.5),(screen.height * 0.5)-(document.body.offsetHeight * 0.5));">
<form action="<?php echo $locatingURL ?>" method="post">
<input type="hidden" name="f_cr_sid" value="<?php echo $f_cr_sid ?>">
<input type="hidden" name="useRemoteDB" value="<?php echo $useRemoteDB ?>">
<div valign="center" align="center">
<table cellspacing="0" cellpadding="0" vspace="0" hspace="0">
<tr>
<td align="center" valign="center">
<br><h2><b>Kurier: <?php echo $f_cr_sid?></b></h2><br>
<?php echo $status_message ?>
<br><br>
<?php echo ($outputOfAllValidZipcodes != "" ? $outputOfAllValidZipcodes . "<br><br>" : "") ?>
<input type="submit" value="Wiederholen">
<!-- <br><br>
<input type="button" value="Schließen" onClick="javascript:window.close();"> -->
</td>
</tr>
</table>
</div>
</form>
</body>
</html>

View File

@@ -0,0 +1,538 @@
<?php
/*=======================================================================
*
* locating_tmobile.php
*
* Autor: Marc Vollmann
*
=======================================================================*/
include_once ("../include/mcglobal.inc.php");
include_once ("../include/auth.inc.php");
include_once ("../include/ranking.inc.php");
include_once ("../include/pnpoly.inc.php");
// Check HTTP-Parameters
getSecHttpVars("1",array("f_act", "customerId", "cscIdRoot", "cscIdActual", "f_cr_sid", "useRemoteDB"));
// Check for authentication access and granted rights
$usrAccessArray["hq"] = "1";
authCheckForAccess($hq_id, $usr_id, $emp_id, "1", $customerId, $cscIdRoot, $cscIdActual);
authCheckEmployeeRights($emp_id, "4", "1");
// ******************************************************
// Very special treatment for access to remote database
include_once ("../include/bwv.inc.php");
$remoteDBisActive = false;
if (BWV2_checkEmpRemoteDBAccess($useRemoteDB, $emp_id)) :
$remoteDBisActive = BWV2_setRemoteDBAccessParameter();
endif;
// ******************************************************
/*
FLOW:
- General definitions
- Get courier-id from http-request
- Search MSISDN from courier-id
- Generate request
- Send request
- Parse response
- Search x,y-coordinates in cells to be valid
- Compute longitude and latitude (transformation)
- Get zipcode from coordinates
- Update zipcode of the courier
- Write to log-file|log-db (employee, datetime, courier-id, msisdn, [zipcode, x_y_of_cell])
- Output zipcode
*/
// ***********************
// * General definitions *
// ***********************
// Proxy und Port fuer HTTPS
$proxy = "";
$port = ":443"; // Remember ":" in HTTP-Header ... $server:$port
// Server innerhalb der Nachricht
// $server = '10.10.1.244'; // E-Plus
// $server = "193.254.134.115"; // D1 - develop
$server = "193.254.161.68"; // D1 - live (https://crisp.t-mobile.de/cgi-bin/vasp.sh)
// Access to a special remote file
$file = "cgi-bin/vasp.sh";
// Request id
// $requestID = "1";
$requestID = rand(1,30000);
// User and password
// $vaspID = "600";
// $password = "mi6t890";
$vaspID = "65";
$password = "Alpha_2405";
// Service ID
$serviceId = "160";
// Maximum of age of locating info
$maxAgeOfLocatingInfoInSeconds = "300";
// Minimum of the granularity
$minOfGranularityInMeter = "99999";
// Client Certificate and Private Key
// $clientcertkey = '-cert ./client-cert-tc/cert.pem -key ./client-cert-tc/key.pem';
$clientcertkey = '-cert cacert.pem -key privkey.pem';
// Path to openssl
// $openssl = 'F:/Install/Security/OpenSSL/openssl';
$openssl = 'openssl';
// Port of openssl
$opensslPort = "9213";
// Only for output
$status_message = "";
// Logging enabled
$loggingEnabled = FALSE;
// Echo enabled
$echoEnabled = FALSE;
// *************
// * Functions *
// *************
function writeLocatingLog($value) {
global $loggingEnabled;
if ($loggingEnabled) :
writeToFile($value);
endif;
}
function openSSL_connect($opensslPort, $completeReq) {
$response = "";
$fp = fsockopen ("127.0.0.1", $opensslPort, $errno, $errstr, 10);
if (!$fp) {
$response = "$errstr ($errno)<br>\n";
} else {
fputs ($fp, $completeReq);
fflush($fp);
// Read header
$httpHeader = "";
$httpBodyLength = 0;
if (!feof($fp)) :
$line = trim(fgets ($fp,1024));
$httpHeader .= trim(fgets ($fp,1024));
while (!feof($fp) && $line != "") {
$line = trim(fgets ($fp,1024));
$httpHeader .= $line;
if (!(strpos($line, "Content-length: ") === FALSE)) :
$httpBodyLength = trim(substr($line, 16));
endif;
}
endif;
if ($httpBodyLength > 0) :
$response .= fgets ($fp, $httpBodyLength + 1);
endif;
// while (!feof($fp)) {
// $response .= fgets ($fp,1024);
// }
fclose ($fp);
}
return $response;
}
// *********************************
// * Search MSISDN from courier-id *
// *********************************
// Get courier-id from the courier-sid (e.g. SIDs: 1013, 1019, etc.)
$cr_id = getFieldValueFromId("courier","cr_sid",$f_cr_sid,"cr_id");
$msisdn = getFieldValueFromId("courier","cr_id",$cr_id,"cr_mobile_pda");
// Remove blanks in MSISDN and check beginning with "49"
// (IMPORTANT: No check for other chars because checked in javascript !!!)
$msisdn = ereg_replace (" ", "", $msisdn);
$msisdn = str_replace("+", "", $msisdn);
if (!ereg("^" . COUNTRY_FON_PREFIX, $msisdn)) :
if (ereg("^0", $msisdn)) :
$msisdn = substr($msisdn, 1);
endif;
$msisdn = COUNTRY_FON_PREFIX . $msisdn;
endif;
// Test-MSISDN D1:
// $msisdn = "491703900198";
// ********************
// * Generate request *
// ********************
/*
TEMPLATES:
Connection Setup
request:
<MESSAGE_TYPE=1><REQUEST_ID=1><VASP_ID=500><PASSWORD=testtest>
response:
<MESSAGE_TYPE=2><REQUEST_ID=1><SESSION_HANDLE=2876><STATUS=0><GMT_DIFFERENCE=2>
Location (n-mal)
request:
<MESSAGE_TYPE=10><REQUEST_ID=1><SESSION_HANDLE=2876><SERVICE_ID=160><MAX_INFO_AGE=6000><MIN_GRANULARITY=2000><MOBILE_ID_TYPE=0><MOBILE_ID=4917112345467><TEXT=48656C6C6F><REQUEST_TIME=20010719102200><GMT_DIFFERENCE=2>
response:
<MESSAGE_TYPE=11><REQUEST_ID=1><SESSION_HANDLE=2876><TIMESTAMP=20010719102321><GEO_REF_SYSTEM=0><POSITION_FORMAT=2><MOBILE_ID_TYPE=0><<MOBILE_ID=491711234567><MOBILE_POSITION=<POSITION_FORMAT=CIRCLE;CENTER=555555,133333;RADIUS=646>><MOBILE_AGE_OF_INFO=-2744><MOBILE_STATUS=0>>
Connection Release
request:
<MESSAGE_TYPE=3><REQUEST_ID=1><SESSION_HANDLE=2876>
response:
<MESSAGE_TYPE=4><REQUEST_ID=1><SESSION_HANDLE=2876><STATUS=0>
error response:
<MESSAGE_TYPE=13><REQUEST_ID=1><SESSION_HANDLE=2876><STATUS=40>
*/
// Define header request
$requestheaderOrg = "POST /" . $file . " HTTP/1.1\r\n" .
"Host: $server$port\r\n" .
"Content-Type: text/plain\r\n" .
"Content-length: LENGTH\r\n\r\n";
// Connection request
$requestConnectionSetup = "<MESSAGE_TYPE=1><REQUEST_ID=" . $requestID . "><VASP_ID=" . $vaspID . "><PASSWORD=" . $password . ">";
$laenge = strlen($requestConnectionSetup);
$requestheader = $requestheaderOrg;
$requestheader = str_replace ("LENGTH", $laenge, $requestheader);
if ($echoEnabled) : echo $requestheader . $requestConnectionSetup . "\n\n\n"; endif;
$response = openSSL_connect($opensslPort, $requestheader.$requestConnectionSetup."\r\n");
if ($echoEnabled) : echo $response . "\n\n\n"; endif;
if (!(strpos($response, "<MESSAGE_TYPE=13>") === FALSE)) :
// Error occurred, no connection ...
$status_message = "Die Verbindung konnte nicht hergestellt werden!";
else :
if ((strpos($response, "<MESSAGE_TYPE=2>") === FALSE)) :
// Error occurred, no session handle delivered ...
$status_message = "Es wurde kein Sessionhandle zurückgeliefert!";
else :
// Get session handle from connection request
$beginPos = strpos($response, "<SESSION_HANDLE=") + 16;
$endPos = strpos($response, "><STATUS");
$sessionHandle = substr($response, $beginPos, $endPos - $beginPos);
if ($echoEnabled) : echo $sessionHandle . "\n\n\n"; endif;
// Define locating request
$requestID++;
$requestLocating = "<MESSAGE_TYPE=10><REQUEST_ID=" . $requestID . ">" .
"<SESSION_HANDLE=" . $sessionHandle . ">" .
"<SERVICE_ID=" . $serviceId . ">" .
"<MAX_INFO_AGE=" . $maxAgeOfLocatingInfoInSeconds . ">" .
"<MIN_GRANULARITY=" . $minOfGranularityInMeter . ">" .
"<MOBILE_ID_TYPE=0>" .
"<MOBILE_ID=" . $msisdn . ">" .
"<REQUEST_TIME=" . getDateTime("year") . getDateTime("month") . getDateTime("day") . getDateTime("hour") . getDateTime("minute") . getDateTime("second") . ">" .
"<GMT_DIFFERENCE=2>";
$laenge = strlen($requestLocating);
$requestheader = $requestheaderOrg;
$requestheader = str_replace ("LENGTH", $laenge, $requestheader);
if ($echoEnabled) : echo $requestheader.$requestLocating . "\n\n\n"; endif;
// Locating request
$response = openSSL_connect($opensslPort, $requestheader.$requestLocating."\r\n");
if ($echoEnabled) : echo $response . "\n\n\n"; endif;
if (!(strpos($response, "<MESSAGE_TYPE=13>") === FALSE)) :
$status_message = "Bei der Lokalisierung trat ein Fehler auf!";
else :
if ((strpos($response, "<MESSAGE_TYPE=11>") === FALSE)) :
$status_message = "Die Lokalisierung war nicht möglich!";
else :
// GET LOCATING INFOS OF THE RESPONSE
// Get session handle from connection request
$beginPos = strpos($response, "<POSITION_FORMAT=CIRCLE;CENTER=") + 31;
$endPos = strpos($response, ";RADIUS");
$coordPair = substr($response, $beginPos, $endPos - $beginPos);
if ($echoEnabled) : echo "CoordPair: " . $coordPair . "<br>"; endif;
$beginPos = strpos($response, "RADIUS=") + 7;
$endPos = strpos($response, ";>><MOBILE_AGE");
$radius = substr($response, $beginPos, $endPos - $beginPos);
if ($echoEnabled) : echo "Radius: " . $radius . "<br>"; endif;
$coordPairArray = spliti(",",$coordPair);
// Transform data
// Example: $coordPair = "555555,133333"
// $coordPairArray[0] = "555555" | $coordPairArray[0] = "133333"
// $x_coord_array[0] = "55" (Stellen 0 und 1) | $x_coord_array[1] = "55" (Stellen 2 und 3) | $x_coord_array[2] = "55" (Stellen 4 und 5)
// $y_coord_array[0] = "13" (Stellen 0 und 1) | $y_coord_array[1] = "33" (Stellen 2 und 3) | $y_coord_array[2] = "33" (Stellen 4 und 5)
$x_coord_array = array();
$x_coord_array[0] = substr($coordPairArray[0], 0, 2);
$x_coord_array[1] = substr($coordPairArray[0], 2, 2);
$x_coord_array[2] = substr($coordPairArray[0], 4);
$y_coord_array = array();
$y_coord_array[0] = substr($coordPairArray[1], 0, 2);
$y_coord_array[1] = substr($coordPairArray[1], 2, 2);
$y_coord_array[2] = substr($coordPairArray[1], 4);
// ***************************************************
// * Compute longitude and latitude (transformation) *
// ***************************************************
$longitude = $y_coord_array[ 0 ] + $y_coord_array[ 1 ] /60 + $y_coord_array[ 2 ] / 3600;
$latitude = $x_coord_array[ 0 ] + $x_coord_array[ 1 ] / 60 + $x_coord_array[ 2 ] / 3600;
// ********************************
// * Get zipcode from coordinates *
// ********************************
if (LOCATING_MODE == "0") :
$zipcode = findZipcodeArea($longitude, $latitude);
else :
// Get nearest coordinates
$sqlquery = "SELECT srvp.srvp_id, srvp.srvp_plz, srvp.srvp_latitude, srvp.srvp_longitude, "
. "SQRT(POW(ABS(srvp.srvp_latitude - $latitude),2) + POW(ABS(srvp.srvp_longitude - $longitude),2)) AS nb"
. " FROM serviceplz AS srvp"
. " ORDER BY nb"
. " LIMIT 0,1";
$result = $db->query($sqlquery);
if (DB::isError($result)) die ("$PHP_SELF: " . $result->getMessage());
// all defined db-fields an titles shall become content of the following arrays
while ($row = $result->fetch_assoc()):
$f_srvp_plz = $row["srvp_plz"]; // Zipcode to be displayed
endwhile;
$result->free();
$zipcode = $f_srvp_plz;
endif;
$status_message = "<b>REALER Standort-PLZ des Kuriers: " . $zipcode . "</b>" . " (" . $longitude . " / " . $latitude . ")<br><br>";
// *********************************
// * Update zipcode of the courier *
// *********************************
$updateRankingTime = TRUE;
// Get current zipcode of the courier out of the table "courier" (cr_locationzipcode) to compare with locating zipcode
$crLocationZipcode = getFieldValueFromId("courier","cr_id",$cr_id,"cr_locationzipcode");
$status_message .= "<b>(Freimeldung des Kuriers: " . $crLocationZipcode . ")</b><br><br>";
if ($zipcode != "" && $crLocationZipcode != "" && is_numeric($crLocationZipcode)) :
// Check current zipcode with locating zipcode
if ($zipcode == $crLocationZipcode) :
$updateRankingTime = FALSE;
else :
// Check locating zipcode is in neighbourhood
// If true then ok => do not update ranking time
// Get the general mediation mode for the headquarter
$mediationMode = MODE_INTERMEDIATION;
if ($mediationMode == "") :
$mediationMode = getFieldValueFromId("headquarters", "hq_id", "$hq_id", "hq_invmode");
endif;
// Get all neighbours for the current zipcode(area)
if ($mediationMode == "1") :
$zicodeArray = getCourierByRanking($crLocationZipcode, "0000010000", "", "");
$zicodeArray = $zicodeArray[5];
else :
$areaIdArray = getCourierByRanking($crLocationZipcode, "0000010000", "", "");
$areaIdArray = $areaIdArray[5];
// Add ID of the main mediation area
$srvpIdZipcode = getFieldValueFromId("serviceplz","srvp_plz",$crLocationZipcode,"srvp_id");
// $srvpaIdMain = getFieldValueFromId("serviceplzareamapping","srvp_id",$srvpIdZipcode,"srvpa_id");
$srvpaIdMain = $db->getOne("SELECT srvpam.srvpa_id FROM serviceplzarea AS srvpa, serviceplzareamapping AS srvpam" .
" WHERE srvpam.srvp_id = '" . $srvpIdZipcode . "' AND srvpa.srvpa_id = srvpam.srvpa_id AND srvpa.hq_id = '" . $hq_id . "'");
if ($areaIdArray == "") : $areaIdArray = array(); endif;
array_push($areaIdArray, $srvpaIdMain);
$areaIdArrayLen = count($areaIdArray);
$outputOfAllValidMainZipcodes = "<b>GÜLTIGE BEREICHE:</b><br>";
$outputOfAllValidMainZipcodes .= "_________________ <br><br>";
$outputOfAllValidMainZipcodes .= "<b>Hauptbereich:</b><br>";
$outputOfAllValidNeighbourZipcodes = "";
$zicodeArray = array();
for ($i = 0; $i < $areaIdArrayLen; $i++) :
if ($i < $areaIdArrayLen - 1) :
$outputOfAllValidNeighbourZipcodes .= "<b>Nachbarbereich " . ($i + 1) . "</b><br>";
endif;
$sqlquery = "SELECT srvp.srvp_plz"
. " FROM serviceplzareamapping AS srvpam, serviceplz AS srvp"
. " WHERE srvpam.srvp_id = srvp.srvp_id AND srvpam.srvpa_id = '" . $areaIdArray[$i] . "'";
$result = $db->query($sqlquery);
if (DB::isError($result)) die ("$PHP_SELF: " . $result->getMessage());
while ($row = $result->fetch_assoc()):
$zicodeArray[] = $row[srvp_plz];
if ($i < $areaIdArrayLen - 1) :
$outputOfAllValidNeighbourZipcodes .= $row[srvp_plz] . "<br>";
else :
$outputOfAllValidMainZipcodes .= $row[srvp_plz] . "<br>";
endif;
endwhile;
$result->free();
if ($i < $areaIdArrayLen - 1) :
$outputOfAllValidNeighbourZipcodes .= "----------------- <br><br>";
else :
$outputOfAllValidMainZipcodes .= "----------------- <br><br>";
endif;
endfor;
$outputOfAllValidZipcodes = $outputOfAllValidMainZipcodes . $outputOfAllValidNeighbourZipcodes;
endif;
$zicodeArrayLen = count($zicodeArray);
for ($i = 0; $i < $zicodeArrayLen; $i++) :
if ($zipcode == $zicodeArray[$i]) :
$updateRankingTime = FALSE;
endif;
endfor;
endif;
$currentTime = getDateTime("0");
if ($updateRankingTime) :
updateStmt("courier", "cr_id", $cr_id, array("cr_locationzipcode", $zipcode, "cr_availabletime", $currentTime));
$status_message .= "Die Rankingposition ging verloren! <br><br>";
else :
// updateStmt("courier", "cr_id", $cr_id, array("cr_locationzipcode", $zipcode));
$status_message .= "Die Rankingposition bleibt erhalten! <br><br>";
endif;
else :
$currentTime = getDateTime("0");
endif;
// Update current position to courier with timestamp
if ($longitude != "" && $latitude != "" &&
substr($longitude , 0, 1) != "0" && substr($latitude , 0, 1) != "0" &&
is_numeric($longitude) && is_numeric($latitude)) :
updateStmt("courier", "cr_id", $cr_id, array("cr_gps_long", $longitude, "cr_gps_lat", $latitude, "cr_gps_time", $currentTime));
endif;
// ***********
// * LOGGING *
// ***********
// Get usr_id of the current employee (session)
$currentSessionUsrId = getFieldValueFromId("employee", "emp_id", $emp_id, "usr_id");
// Loose Ranking yes/no
$looseRanking = "NO";
if ($updateRankingTime) : $looseRanking = "YES"; endif;
// Write logdata into log database
writeToLogDB("27",$hq_id,"0",$currentSessionUsrId,$cr_id,$f_cr_sid,"","LONG=".$longitude."|LAT=".$latitude."|ZIP_REAL=".$zipcode."|ZIP_FREE=".$crLocationZipcode."|NO=".$msisdn."|LRANK=".$looseRanking);
// ********************
// * Close connection *
// ********************
$requestID++;
$requestConnectionRelease = "<MESSAGE_TYPE=3><REQUEST_ID=" . $requestID . "><SESSION_HANDLE=" . $sessionHandle . ">";
$laenge = strlen($requestConnectionRelease);
$requestheader = $requestheaderOrg;
$requestheader = str_replace ("LENGTH", $laenge, $requestheader);
if ($echoEnabled) : echo $requestheader.$requestConnectionRelease . "<br><br><br>"; endif;
// Connect Release
$response = openSSL_connect($opensslPort, $requestheader.$requestConnectionRelease."\r\n");
endif;
endif;
endif;
endif;
?>
<html lang="de">
<head>
<title>ORTUNG</title>
<link rel="stylesheet" type="text/css" href="../css/phoenix.css">
</head>
<body onLoad="this.moveTo((screen.width * 0.5)-(document.body.offsetWidth * 0.5),(screen.height * 0.5)-(document.body.offsetHeight * 0.5));">
<form action="../locating/locating_tmobile.php" method="post">
<input type="hidden" name="f_cr_sid" value="<?php echo $f_cr_sid ?>">
<input type="hidden" name="useRemoteDB" value="<?php echo $useRemoteDB ?>">
<div valign="center" align="center">
<table cellspacing="0" cellpadding="0" vspace="0" hspace="0">
<tr>
<td align="center" valign="center">
<b>Kurier-SID: <?php echo $f_cr_sid?></b><br><br>
MSISDN: <?php echo $msisdn?><br><br>
<br><br><br>
<input type="submit" value="Wiederholen">
<br><br>
<input type="button" value="Schließen" onClick="javascript:window.close();">
<br><br><br><br><br>
<?php echo $status_message ?>
<br><br><br><br><br>
<?php echo $outputOfAllValidZipcodes ?>
</td>
</tr>
</table>
</div>
</form>
</body>
</html>

125
html/locating/map.inc.php Normal file
View File

@@ -0,0 +1,125 @@
<?php
include_once ("../include/dbglobal.inc.php");
include_once ("../include/ranking.inc.php"); // Checks ranking to be lost or not
$today = getdate();
$start_time = date("Y-m-d H:i:s", mktime(0, 0, 0, $today['mon'], $today['mday'], $today['year']));
//list ($zipcode, $jb_id, $hq_id_string) = getHttpVars(array("zipcode", "jb_id", "hq_id_string"));
$zipcode = getFieldValueFromId("address", "ad_id", getFieldValueFromClause("tour", "ad_id", "jb_id = '" . $jb_id . "' AND tr_sort = '1'"), "ad_zipcode");
$hq_id_string = $hq_id;
include("../jobs/job_courier.inc.php");
$vht_id_str_js = str_replace("var vht_id_str=new Array();\n", "", $vht_id_str_js);
//$js_args = "";
//if (isset($jb_id) && $jb_id != "")
// $js_args = $jb_id . ", '" . $zipcode . "'" . ", '" . $hq_id_string . "'";
$companyIds = array();
$sqlquery =
"SELECT cmp.cmp_id, cr.cr_sid"
. " FROM company AS cmp, courier AS cr"
. " WHERE "
. " cmp.cmp_id = cr.cmp_id AND"
. " cr.hq_id = '" . $hq_id . "' AND"
. " cr.cr_sid != '' AND NOT (cr.cr_sid IS NULL)";
$res = $db->query($sqlquery);
if (DB::isError($res)) reportDie ("$PHP_SELF: '$sqlquery'" . $res->getMessage());
while ($row = $res->fetch_assoc()):
$companyIds[$row["cr_sid"]] = "companyId=" . ec($row["cmp_id"]);
endwhile;
$res->free();
$vhtIds = array();
$sqlquery =
"SELECT mt_sort, mt_value FROM `metatype` WHERE mt_type = 'vehicletype'";
$res = $db->query($sqlquery);
if (DB::isError($res)) reportDie ("$PHP_SELF: '$sqlquery'" . $res->getMessage());
while ($row = $res->fetch_assoc()):
$vhtIds[$row["mt_sort"]] = $row["mt_value"];
endwhile;
$res->free();
//$current_jobs = array();
//$sqlQuery = "SELECT jb_id, jb_ordertime, cr_sid FROM job WHERE jb_status = 1 ORDER BY jb_ordertime ASC";
//$res = $db->query($sqlQuery);
//if (DB::isError($res)) reportDie ("$PHP_SELF: '$sqlQuery': " . $res->getMessage());
//while ($row = $res->fetch_assoc()):
// $current_jobs[$row["cr_sid"]][] = array($row["jb_id"], $row["jb_ordertime"]);
//endwhile;
//$res->free();
function formDate($sqlDate) {
global $today;
if ($today['mon'] == substr($sqlDate, 5, 2)
&& $today['mday'] == substr($sqlDate, 8, 2)
&& $today['year'] == substr($sqlDate, 0, 4)) {
return substr($sqlDate, 11, 5) . " Uhr";
}
return substr($sqlDate, 11, 5) . " Uhr, " . substr($sqlDate, 8, 2) . "." . substr($sqlDate, 5, 2) . ".";
}
function mk_text($cr_locationzipcode, $cr_availabletime, $cr_gps_time, $cr_gps_type, $cr_available, $cr_sid, $vht_id, $cr_mobile_pda, $usr_phone, $usr_phone2, $jb_id) {
global $db, $companyIds, $current_jobs, $customer_special, $courier_special, $vhtIds, $cs_id, $usr_id;
$vhtType = $vhtIds[$vht_id];
$cr_gps_type_text = "";
if ($cr_gps_type == 0) {
$cr_gps_type_text = "unbestimmt";
} elseif ($cr_gps_type == 1) {
$cr_gps_type_text = "LBS";
} elseif ($cr_gps_type == 2) {
$cr_gps_type_text = "GPS";
} elseif ($cr_gps_type == 3) {
$cr_gps_type_text = "Network";
} elseif ($cr_gps_type == 9) {
$cr_gps_type_text = "Ortung aus";
}
$detailLink = "";
if (isset($current_jobs[$cr_sid]))
foreach ($current_jobs[$cr_sid] AS $jobA) {
$detailLink .= ($customer_special
? ""
: "<a href=\"javascript:popupWindow(\'../admin/jb_detail.php?job_id=" . $jobA[0] . "\',\'Auftrag\',\'\');\">" . $jobA[0] . " (" . formDate($jobA[1]) . ")</a><br>\\n");
$jb_tourdataA = explode("|", $jobA[4]);
$plzA = explode(";", $jb_tourdataA[0]);
$pickedUp1 = "";
$pickedUp2 = "";
if ($jobA[5] == 1):
$pickedUp1 = "<span style=\"color:red\">(</span>";
$pickedUp2 = "<span style=\"color:red\">)</span>";
endif;
$detailLink .= $pickedUp1 . $plzA[0] . $pickedUp2 . "&nbsp;-&gt;&nbsp;" . ((count($plzA) > 2) ? "...&nbsp;-&gt;&nbsp;" : "") . $plzA[count($plzA) - 1] . "<br>\\n";
}
if ($detailLink != "")
$detailLink .= "<br>";
$cr_sid_link = "";
if ($jb_id != "") {
$jb_offer = $db->getOne("SELECT jb_offer FROM job WHERE jb_id = " . $jb_id);
if ($jb_offer == 0) {
$cr_sid_link = ($customer_special ? "" : "<center><b><a href=\"javascript:setCourier(\'" . $jb_id . "\',\'" . $cr_sid . "\');\">" . "[Auftrag zuweisen]" . "</a></b></center>");
} else {
$cr_sid_link = ($customer_special ? "" : "<center><b>" . "[Auftrag ist ein Angebot]" . "</b></center>");
}
}
return
"'" .
"<center><b>" .
($customer_special ? "" : "<a href=\"../admin/courier_special.php?" . $companyIds[$cr_sid] . "\" target=\"_blank\">") .
ereg_replace("[^[:digit:]+]", "", $cr_sid) . " ($vhtType)<\/a></b>" .
"<br>" . ($customer_special ? "Tel.: " . (trim($usr_phone) != "" ? $usr_phone : $usr_phone2) : $cr_mobile_pda) .
"<br>" . $cr_sid_link .
"<br>" . $detailLink . "\\n" .
($customer_special ? "" : "<i>Freimeldung:</i> " . $cr_locationzipcode . "<br>" . formDate($cr_availabletime) . "<br>\\n" ) .
"<i>Letzte Ortung:</i> " . formDate($cr_gps_time) . " (" . $cr_gps_type_text . ")" .
($customer_special ? "" : "<br>" .
($cr_available == 1
? "<a href=\"../locating/locating.php?f_cr_sid=" . $cr_sid . "\" target=\"_blank\">(Neue Ortung)</a></center>"
: "<span style=\"color:red\">(nicht online)</span>")) .
"'";
}
?>

52
html/locating/map.js Normal file
View File

@@ -0,0 +1,52 @@
// Examples taken from:
// http://leafletjs.com/examples/quick-start/
// http://openwebcc.github.io/lv/examples/index.html
// https://meggsimum.de/?p=86
// http://stackoverflow.com/questions/9394190/leaflet-map-api-with-google-satellite-layer
var baseMaps = {
osm_de : L.tileLayer("https://{s}.tile.openstreetmap.de/tiles/osmde/{z}/{x}/{y}.png", {
attribution : '<a href="http://www.openstreetmap.org/">Karte hergestellt aus OpenStreetMap-Daten</a> | Lizenz: <a rel="license" href="http://opendatacommons.org/licenses/odbl/">Open Database License (ODbL)</a>'
}),
osm : L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
attribution: '&copy; <a href="http://osm.org/copyright">OpenStreetMap contributors</a>'
}),
osm_bw : L.tileLayer('https://tiles.wmflabs.org/bw-mapnik/{z}/{x}/{y}.png', {
attribution: '&copy; <a href="http://osm.org/copyright">OpenStreetMap contributors</a>'
})
// oepnv : L.tileLayer("http://tile.xn--pnvkarte-m4a.de/tilegen/{z}/{x}/{y}.png", {
// attribution: 'Map data &copy; <a href="http://www.openstreetmap.org/">OpenStreetMap</a> and contributors <a href="http://creativecommons.org/licenses/by-sa/2.0/">CC-BY-SA</a>'
// }),
};
var map = L.map('map', {
center: homeCoords,
zoom: homeZoom,
layers : [baseMaps.osm_de].concat(defaultLayers)
});
var layerControl = L.control.layers({
"OSM Mapnik german style" : baseMaps.osm_de,
"OSM Mapnik" : baseMaps.osm,
"OSM Mapnik B&W" : baseMaps.osm_bw
// "&Ouml;PNV Karte" : baseMaps.oepnv,
},
overlayMaps
).addTo(map);
L.control.scale({
'imperial': false
}).addTo(map);
L.control.coordinates().addTo(map);
map.on('popupopen', onPopupOpen);
//// http://www.liedman.net/leaflet-routing-machine/tutorials/basic-usage/
//L.Routing.control({
// waypoints: [
// L.latLng(53.626, 9.838),
// L.latLng(53.80777, 10.14576)
// ],
// routeWhileDragging: false
//}).addTo(map);

643
html/locating/map.php Normal file
View File

@@ -0,0 +1,643 @@
<?php
include_once("../include/global.inc.php");
include_once("../include/auth.inc.php");
$usr_type = getFieldValueFromId("user", "usr_id", $usr_id, "usr_type");
if ($usr_type != "1"):
$die_text = "Keine Berechtigung";
if ($usr_type == "2"):
$csc_id = getFieldValueFromId("employee", "usr_id", $usr_id, "csc_id");
$cs_id = getFieldValueFromId("costcenter", "csc_id", $csc_id, "cs_id");
if (getParameterValue("0", "MASK_JB_MAP_VIEW_ENABLED_" . $cs_id, "0") != "1"):
die($die_text);
endif;
else:
die($die_text);
endif;
endif;
include_once ("../include/image.inc.php");
include_once ("../locating/xServer.inc.php");
$standalone = "1"; // has to be set before including "ranking.inc.php"
include_once ("../include/ranking.inc.php");
$hq_id = $_SESSION['hq_id'];
if ($hq_id == "") : $hq_id = $HTTP_SESSION_VARS['hq_id']; endif;
list ($jb_id) = getHttpVars(array("jb_id"));
if ($jb_id != ""):
$hq_id = getFieldValueFromId("job", "jb_id", $jb_id, "hq_id");
endif;
include_once ("../locating/map.inc.php");
$allCoords = array();
$today = getdate();
function getCoordsOffset($x, $y) {
global $allCoords;
$xx = round($x, 5);
$yy = round($y, 5);
foreach ($allCoords as $coords) {
if ($coords[0] == $xx && $coords[1] == $yy):
return $coords[2]++;
endif;
}
$allCoords[] = array($xx, $yy, 1);
return 0;
}
// Makes an image more transparent
function getTransparency2 ($im, $scalingFactorPercent = "0", $imVhtSizeX = "200", $imVhtSizeY = "200") {
if ($im) :
// Get size of the original image
$imSizeX = imagesx($im);
$imSizeY = imagesy($im);
// Create a new white temporary image for merging with original image
// $imTmp = @imagecreate ($imSizeX, $imSizeY) or die ("Cannot Initialize new GD image stream");
$imTmp = @imagecreate ($imVhtSizeX, $imVhtSizeY) or die ("Cannot Initialize new GD image stream");
imagecolorallocate ($imTmp, 237, 237, 237);
// int ImageCopy ( int dst_im, int src_im, int dst_x, int dst_y, int src_x, int src_y, int src_w, int src_h);
imagecopymerge ( $im, $imTmp, 0, 0, 0, 0, $imSizeX, $imSizeY, $scalingFactorPercent);
// $index = imagecolorexact($im, 255, 255, 255);
// imagecolortransparent($im, $index);
// $transpCol = imagecolorallocate ($im, 255, 255, 255);
// imagecolortransparent($im, $transpCol);
endif;
return $im;
}
// Display courier image with vehicle icon
function generateVehicleImage ($jb_id, $crSid, $vhtID = "2", $crGpsTime = "00-00-00 00:00:00", $cr_occupied, $cr_locationzipcode) {
global $hqMnemonic, $searchCrSid, $cancel_man;
//echo $crSid."<br>\n". $vhtID ."<br>\n". $crGpsTime ."<br>\n". $cr_occupied;
$availCol = "red";
if ($cr_occupied != 1):
$availCol = "green";
if (in_array($crSid, $cancel_man))
$availCol = "pink";
for ($i = 0; $i <= 4; $i++):
if (!is_numeric(substr($cr_locationzipcode, $i, 1))):
$availCol = "orange";
break;
endif;
endfor;
endif;
//echo "$crSid, $cr_locationzipcode, $availCol \n";
$vhtFileName = "";
if ($vhtID == "2") : $vhtFileName = "pkw_" . $availCol . ".png" ; endif;
if ($vhtID == "3") : $vhtFileName = "kombi_" . $availCol . ".png" ; endif;
if ($vhtID == "4") : $vhtFileName = "kasten_" . $availCol . ".png" ; endif;
if ($vhtID == "5") : $vhtFileName = "bus_" . $availCol . ".png" ; endif;
if ($vhtID == "6") : $vhtFileName = "grbus_" . $availCol . ".png" ; endif;
if ($vhtID == "7") : $vhtFileName = "lkw_" . $availCol . ".png" ; endif;
if ($vhtID > "7") : $vhtFileName = "lkw_" . $availCol . ".png" ; endif;
if ($vhtFileName != "") :
$imVht = @ImageCreateFromPNG ("../images/" . $vhtFileName);
$imVhtSizeX = imagesx($imVht);
$imVhtSizeY = imagesy($imVht);
// Set transparency of the vehicle icon
$currSeconds = mktime(date("H"), date("i"), date("s"), date("m"), date("d"), date("Y"));
$crGpsTimeSeconds = mktime(substr($crGpsTime,11,2), substr($crGpsTime,14,2), substr($crGpsTime,17,2), substr($crGpsTime,5,2), substr($crGpsTime,8,2), substr($crGpsTime,0,4));
$diffMinutes = (($currSeconds - $crGpsTimeSeconds) / 60);
$transparencyScaleVehicleIcon = min((floor($diffMinutes / 15) * 10) - 10, 80);
// $boxPointsArray = imagettftext ($im, 10, 0, 300, 500, $lineColBlack, $textFontPath, $transparencyScaleVehicleIcon);
// setTextBox ($im, $boxPointsArray, "2", $lineColBlack);
if ($transparencyScaleVehicleIcon > 0) :
$imVht = getTransparency2($imVht, $transparencyScaleVehicleIcon, $imVhtSizeX, $imVhtSizeY);
endif;
// Search for a special vehicle
if ($searchCrSid != "" && strtolower($crSid) == strtolower($searchCrSid)) :
// Zuppel the box ... :-)
$boxPointsArray[0] += 2; $boxPointsArray[5] += 2; $boxPointsArray[6] += 2; $boxPointsArray[7] += 2;
$lineColRed = imagecolorallocate ($imVht, 255, 0, 0);
setTextBox ($imVht, $boxPointsArray, "2", $lineColRed);
endif;
$imMark = @ImageCreateFromPNG ("../images/marker_white_big.png");
imagealphablending($imMark, true);
imagesavealpha($imMark, true);
$lineCol = imagecolorallocate ($imMark, 0, 0, 0);
$crSidNo = ereg_replace("[^[:digit:]+]","",$crSid);
imagettftext ($imMark, 8, 0, 10, 12, $lineCol, "../include/arial.ttf", $crSidNo);
$posx = (imagesy($imMark) - $imVhtSizeX) / 2 + 2;
$posy = (imagesx($imMark) - $imVhtSizeY) / 2 + 2;
imagecopy($imMark, $imVht, $posx, $posy, 0, 0, $imVhtSizeX, $imVhtSizeY);
imagepng($imMark, "../temp/captchas/" . $jb_id . $crSid . ".png");
return array($imVhtSizeX, $imVhtSizeY);
endif;
}
function generateStationImage ($jb_id, $tr_sort, $tr_status) {
$imgFilename = "../temp/captchas/" . $jb_id . "-" . $tr_sort . ".png";
$imMark = ($tr_status == 1 ? @ImageCreateFromPNG ("../images/marker_green.png") : @ImageCreateFromPNG ("../images/marker_red.png"));
imagealphablending($imMark, true);
imagesavealpha($imMark, true);
$lineCol = imagecolorallocate ($imMark, 0, 0, 0);
$x = 11;
if ($tr_sort > 9)
$x = 8;
imagettftext ($imMark, 8, 0, $x, 14, $lineCol, "../include/arial.ttf", $tr_sort);
imagepng($imMark, $imgFilename);
return $imgFilename;
}
$errorMsg = "";
$hq_marker = "../images/marker_sb.png";
if ($hq_id >= 100)
$hq_marker = "../images/marker_ht.png";
$lat = 0;
$long = 0;
// Zentrale
$sqlquery = "SELECT hq_gps_long, hq_gps_lat FROM headquarters WHERE hq_id = '$hq_id'";
$markers_javascript = "";
$res = $db->query($sqlquery);
if (DB::isError($res))
die ("$PHP_SELF: '$sqlquery' : " . $res->getMessage());
if ($row = $res->fetch_assoc()):
$lat = $row["hq_gps_lat"];
$long = $row["hq_gps_long"];
$markers_javascript .= "setMarker($long, $lat, '$hq_marker', size1, offset1, popupSize1, '&nbsp;Zentrale', 'central');\n";
endif;
$res->free();
// Wenn ein Auftrag angegeben und dieser bereits einen Fahrer hat, dann nur diesen in die Liste der Fahrer übernehmen
$cr_sid = "";
$customer_special = false;
if ($usr_type == 2 || $usr_id == 10041): //HTM18156 || admin_m
$cr_sid = getParameterValue("0", "MASK_JB_MAP_VIEW_COURIERS_" . $cs_id, "0");
if ($usr_id == 10041)
$cr_sid = "M047','M048','M072','M099";
$customer_special = true;
endif;
$cancel_man = array();
if ($jb_id != ""):
$jb_status_clause = " AND NOT (jb_status IN (8,9))";
if ($usr_type == 2)
$jb_status_clause = " AND jb_status = 1";
$sqlquery = "SELECT cr_id, cr_sid, hq_id FROM job WHERE jb_id = '$jb_id'" . $jb_status_clause;
//echo $sqlquery . "<br>\n";
$res = $db->query($sqlquery);
if (DB::isError($res))
die ("$PHP_SELF: '$sqlquery' : " . $res->getMessage());
if ($row = $res->fetch_assoc()):
$cr_id = trim($row["cr_id"]);
$cr_sid = trim($row["cr_sid"]);
$hq_id = trim($row["hq_id"]);
endif;
$res->free();
// die ablehnenden Fahrer (logo_id = 11) sollen in einer anderen Farbe aufgeführt werden
// Testaufträge: SELECT *, COUNT(*) FROM log, phoenix.job WHERE logo_id = 11 AND phoenix_log.log.hq_id = 3 AND log_createtime > "2016-11-03 00:00:00" AND phoenix_log.log.jb_id = phoenix.job.jb_id AND phoenix.job.jb_status = 9 GROUP BY phoenix.job.jb_id
$sqlquery = "SELECT cr_sid FROM phoenix_log.log WHERE jb_id = " . $jb_id . " AND logo_id = 11";
$res = $db->query($sqlquery);
if (DB::isError($res)) reportDie ("$PHP_SELF: '$sqlquery'" . $res->getMessage());
while ($row = $res->fetch_assoc()):
$cancel_man[] = $row["cr_sid"];
endwhile;
$res->free();
endif;
//$is_occupied = array();
//$sqlQuery = "SELECT DISTINCT cr_sid FROM job WHERE jb_status = 1";
//$res = $db->query($sqlQuery);
//if (DB::isError($res)) reportDie ("$PHP_SELF: '$sqlQuery': " . $res->getMessage());
//while ($row = $res->fetch_assoc()):
// $is_occupied[$row["cr_sid"]] = 1;
//endwhile;
//$res->free();
$hq_id_refresh = $hq_id;
if ($cr_sid == ""):
list ($cr_sid) = getHttpVars(array("cr_sid"));
$hq_id_refresh = 0;
endif;
$sqlquery = "SELECT cr_sid, vht_id, cr_locationzipcode, cr_available, cr_availabletime, cr_gps_long, cr_gps_lat, cr_gps_time, cr_gps_type, cr_mobile_pda, usr_phone, usr_phone2 FROM courier, user WHERE courier.hq_id = '$hq_id' AND (cr_sid != '' AND NOT(cr_sid IS NULL)) AND cr_gps_time > '" . $start_time . "' AND courier.usr_id = user.usr_id"; //AND cr_available = 1 ORDER BY cr_gps_time, cr_sid";
$show_couriers = 1;
if (trim($cr_sid) != "" || $usr_type == "2"):
$sqlquery = "SELECT cr_sid, vht_id, cr_locationzipcode, cr_availabletime, cr_gps_long, cr_gps_lat, cr_gps_time, cr_gps_type, cr_mobile_pda, usr_phone, usr_phone2 FROM courier, user WHERE cr_sid IN ('$cr_sid') AND cr_gps_time > '" . $start_time . "' AND courier.usr_id = user.usr_id";
if ($jb_id != ""):
$locatingStateArray = checkLocatingState($cr_id);
if ($locatingStateArray[0] == "1")
$show_couriers = 0;
endif;
endif;
//echo $sqlquery . "<br>\n";
$res = $db->query($sqlquery);
if (DB::isError($res)) die ("$PHP_SELF: '$sqlquery' : " . $res->getMessage());
$i = 1;
$cr_sid_list = "";
while ($row = $res->fetch_assoc()):
$imgSize = generateVehicleImage($jb_id, $row["cr_sid"], $row["vht_id"], $row["cr_gps_time"], $is_occupied[$row["cr_sid"]], $row["cr_locationzipcode"]);
$markers_javascript .=
($jb_id != "" && $usr_type == "1"
? "if (typeof vht_id_str['" . $row["cr_sid"] . "'] != 'undefined' && !cr_sid_is_blocked('" . $row["cr_sid"] . "'))\n"
: "") .
" setMarker(". $row["cr_gps_long"] . ", " . $row["cr_gps_lat"] . ", '../temp/captchas/" . $jb_id . $row["cr_sid"] . ".png', size2.clone(), offset2.clone(), popupSize2.clone(),\n" .
mk_text($row["cr_locationzipcode"], $row["cr_availabletime"], $row["cr_gps_time"], $row["cr_gps_type"], $row["cr_available"], $row["cr_sid"], $row["vht_id"], $row["cr_mobile_pda"], $row["usr_phone"], $row["usr_phone2"], $jb_id) .
", 'couriers');\n";
$cr_sid_list .= ($cr_sid_list == "" ? "\'" : ",\'") . $row["cr_sid"] . "\'";
if (trim($cr_sid) != ""):
$lat = $row["cr_gps_lat"];
$long = $row["cr_gps_long"];
endif;
endwhile;
$res->free();
// Stationen eines Auftrages
if ($jb_id != ""):
$sqlquery = "SELECT ad_street, ad_zipcode, ad_city, ad_country, tr_sort, tr_comp, tr_comp2, tr_hsno, tr_remark, tr_person, tr_phone, tr_status, tr_sign, tr_signname, tr_ware_from_to, " .
"tr_finishtime, tr_commission_no, tr_status, tr_finishtime FROM tour, address WHERE jb_id = $jb_id AND tour.ad_id = address.ad_id ORDER BY tr_sort";
$res = $db->query($sqlquery);
if (DB::isError($res)) die ("$PHP_SELF: '$sqlquery' : " . $res->getMessage());
while ($row = $res->fetch_assoc()):
$imgFilename = generateStationImage($jb_id, $row["tr_sort"], $row["tr_status"]);
$coords = XSfindAddress($row["ad_country"], $row["ad_zipcode"], $row["ad_city"], $row["ad_street"], $row["tr_hsno"]);
if ($coords[0][0] != 100):
// $errorMsg .= "&nbsp;Fehlerhafte Adresse in Station [" . $row["tr_sort"] . "]: [" .
// $row["ad_zipcode"] . " " . $row["ad_city"] . " " . $row["ad_street"] . " " . $row["tr_hsno"] . "]\n";
else:
$finishMsg = "<br>\\nNoch nicht erledigt";
if ($row["tr_status"] == 1):
$finishMsg = "<br>\\nErledigt um " . formDate($row["tr_finishtime"]);
endif;
$offsetAdd = getCoordsOffset($coords[0][1], $coords[0][2]) * 13;
$markers_javascript .= "var specialOffset" . $row["tr_sort"] . " = new OpenLayers.Pixel(" . (-9 + $offsetAdd) . ", " . (-28 + ($offsetAdd * -1)) . ");\n";
$markers_javascript .= "setMarker(". $coords[0][1] . ", " . $coords[0][2] . ", '$imgFilename', size3.clone(), specialOffset" . $row["tr_sort"] . ", popupSize3.clone(),\n" .
" '<center>" . str_replace("'", "\'", $row["tr_comp"]) . " " . str_replace("'", "\'", $row["tr_comp2"]) . "<br>\\n" . str_replace("'", "\'", $row["ad_street"]) . " " . str_replace("'", "\'", $row["tr_hsno"]) . "<br>\\n" . str_replace("'", "\'", $row["ad_zipcode"]) . " " . str_replace("'", "\'", $row["ad_city"]) . "<br>\\n" . $finishMsg . "</center>', 'stations');\n";
endif;
endwhile;
$res->free();
endif;
$sqlquery = "SELECT ad_street, ad_zipcode, ad_city, ad_country, stk_name, stk_hsno FROM stock, address WHERE stock.ad_id > 0 AND stock.ad_id = address.ad_id";
$res = $db->query($sqlquery);
if (DB::isError($res)) die ("$PHP_SELF: '$sqlquery' : " . $res->getMessage());
while ($row = $res->fetch_assoc()):
$imgFilename = "../images/marker_stock.png";
$coords = XSfindAddress($row["ad_country"], $row["ad_zipcode"], $row["ad_city"], $row["ad_street"], $row["stk_hsno"]);
if ($coords[0][0] != 100):
// $errorMsg .= "&nbsp;Fehlerhafte Adresse in Lager [" . $row["stk_name"] . "]: [" .
// $row["ad_zipcode"] . " " . $row["ad_city"] . " " . $row["ad_street"] . " " . $row["stk_hsno"] . "]\n";
else:
$markers_javascript .= "setMarker(". $coords[0][1] . ", " . $coords[0][2] . ", '$imgFilename', size3.clone(), offset3.clone(), popupSize3.clone(),\n" .
" '<center>" . $row["stk_name"] . "<br>\\n" . $row["ad_street"] . " " . $row["stk_hsno"] . "<br>\\n" . $row["ad_zipcode"] . " " . $row["ad_city"] . "<br>\\n</center>', 'stocks');\n";
endif;
endwhile;
$res->free();
//echo $_SERVER['HTTP_USER_AGENT'];
//$heightCorr = 0;
//$widthCorr = 0;
$heightCorr = 120;
$widthCorr = 4;
if(stristr($_SERVER['HTTP_USER_AGENT'], 'Firefox/4')):
$heightCorr = 139;
$widthCorr = 4;
endif;
if(stristr($_SERVER['HTTP_USER_AGENT'], 'Firefox/3')):
$heightCorr = 140;
$widthCorr = 5;
endif;
if(stristr($_SERVER['HTTP_USER_AGENT'], 'Firefox/2')):
$heightCorr = 116;
$widthCorr = 4;
endif;
if(stristr($_SERVER['HTTP_USER_AGENT'], 'Firefox/20')):
$heightCorr = 120;
$widthCorr = 4;
endif;
//echo $heightCorr;
//echo $widthCorr;
?>
<html>
<head>
<title>KARTENDARSTELLUNG
<?php
if ($jb_id != ""):
echo " Auftrag Nr. " . $jb_id;
endif;
?>
</title>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<meta name="description" content="votian"> <meta name="keywords" content="votian"><link rel="stylesheet" type="text/css" href="../css/phoenix.css">
<script src="../js/jquery.js"></script>
<!--
<script src="http://www.openlayers.org/api/OpenLayers.js"></script>
-->
<script src="../include/openlayers/OpenLayers.js"></script>
<!--
<script src="http://www.openstreetmap.org/openlayers/OpenStreetMap.js"></script>
<script src='http://maps.google.com/maps?file=api&amp;v=2&amp;key=ABQIAAAA3HdfrnxFAPWyY-aiJUxmqRTJQa0g3IQ9GZqIMmInSLzwtGDKaBQ0KYLwBEKSM7F9gCevcsIf6WPuIQ'></script>
<script src="http://api.maps.yahoo.com/ajaxymap?v=3.0&appid=euzuro-openlayers"></script>
-->
<?php
if ($jb_id != "")
echo
"<script src=\"../include/lib_courier.js\" type=\"text/javascript\"></script>" .
"<script type=\"text/javascript\">\n" .
"<!--\n" .
"var vht_id_str = new Array();\n" .
$vht_id_str_js .
$cr_id_order_list_blocked_js .
"function setCourier(jb_id,cr_sid)\n" .
"{\n" .
" addmsg = vht_id_str[cr_sid];\n" .
// " var penalty = 0;" .
// " if (this.document.reset_cr_availabletime_form.reset_cr_availabletime.checked) {" .
// " addmsg = \"\n(Freimeldezeit von \" + this.document.reset_cr_availabletime_form.cur_cr_sid.value + \" wird aktualisiert)\" + addmsg;" .
// " penalty = 1;" .
// " }" .
" if (confirm(\"Auftrag \" + jb_id + \" dem Transporteur \" + cr_sid + \" zuweisen?\" + addmsg)) {\n" .
// " this.opener.setCourier(jb_id,cr_sid,penalty);" .
// " alert ('../include/ajaxReqMap.php' + '&cr_sid=' + cr_sid + '&hq_id=' + hq_id + '&customer_special=$customer_special' + '&jb_id=$jb_id' + '&f_act=setCourier');\n" .
" ajaxRequestGet('../include/ajaxReqMap.php', 'cr_sid=' + cr_sid + '&hq_id=' + hq_id + '&customer_special=$customer_special' + '&jb_id=$jb_id' + '&f_act=setCourier');\n" .
" self.close();\n" .
" };\n" .
"};\n" .
"function cr_sid_is_blocked(cr_sid)\n" .
"{\n" .
" for (var i = 0; i < cr_id_order_list_blocked.length; i++)\n" .
" if (cr_id_order_list_blocked[i] == cr_sid)\n" .
" return true;\n" .
" return false;\n" .
"}\n" .
"-->\n\n" .
"</script>\n";
?>
<noscript>
<center>
<b><br>JavaScript ist nicht verf&uuml;gbar. Bitte aktivieren Sie JavaScript<br><br>
in Ihrem Browser, damit diese Seite ordnungsgem&auml;&szlig; funktioniert!</b><br><br>
</center>
</noscript>
</head>
<body>
<div style="display: table; height: 100%; #position: relative; overflow: hidden; margin:auto;">
<div style=" #position: absolute; #top: 50%;display: table-cell; vertical-align: middle;">
<div style=" #position: relative; #top: -50%; border: 2px solid black;">
<div id="map" style="width:1007px; height:675px; vertical-align:middle;">
<script type="text/javascript">
// JQuery.Request (GET)
function ajaxRequestGet(url, data) {
$.ajax({
type: "GET",
url: url,
data: data,
async: false,
cache: false,
success: function(msg){eval(msg);}
});
}
function popupWindow(url,title,config) {
var widthPopupWin = screen.width - 80;
var heightPopupWin = screen.height - 180;
var leftPopupWin = (screen.width / 2) - (widthPopupWin / 2);
var topPopupWin = (screen.height / 2) - (heightPopupWin / 2);
var popup;
popup = window.open(url,title,
"dependent=yes,width=" + widthPopupWin + ",height=" +
heightPopupWin +",left=" + leftPopupWin + ",top=" + topPopupWin +
",scrollbars=yes");
}
/********************************************************************************/
// Quelle für event-handling: http://forum.openstreetmap.org/viewtopic.php?id=5537
function setMarker(lon, lat, markerFile, iconSize, offset, popupSize, txt, layerName){
var icon = new OpenLayers.Icon(markerFile, iconSize, offset);
var lonLat = new OpenLayers.LonLat(lon, lat).transform(new OpenLayers.Projection("EPSG:4326"), map.getProjectionObject());
var popup = new OpenLayers.Popup.AnchoredBubble("chicken", lonLat, popupSize, txt, icon, true);
var feature = new OpenLayers.Feature(layerName, lonLat.clone(), popup);
feature.closeBox = true;
// feature.popupClass = OpenLayers.Class(OpenLayers.Popup.AnchoredBubble);
// feature.data.size = new OpenLayers.Size(100, 80);
// feature.data.popupContentHTML = txt;
// feature.data.overflow = "hidden";
var marker = new OpenLayers.Marker(lonLat.clone(), icon.clone());
marker.feature = feature;
var markerClick = function(evt) {
if (this.popup == null) {
this.popup = this.createPopup(this.closeBox);
map.addPopup(this.popup);
this.popup.setSize(popupSize.clone());
this.popup.setContentHTML(txt);
this.popup.show();
} else {
this.popup.toggle();
}
OpenLayers.Event.stop(evt);
};
marker.events.register("mousedown", feature, markerClick);
if (layerName == 'central')
central.addMarker(marker);
if (layerName == 'couriers')
couriers.addMarker(marker);
if (layerName == 'stations')
stations.addMarker(marker);
if (layerName == 'stocks')
stocks.addMarker(marker);
}
var crSidList = <?php echo "'" . $cr_sid_list . "'"; ?>;
var hq_id = <?php echo "'" . $hq_id_refresh . "'"; ?>;
var prevRetValue = new Array();
function updateLayer(layerName) {
var tmpMarker;
var tmpUrl;
var tmpArr;
var crSid;
//alert ('../include/ajaxReqMap.php?cr_sid=' + crSidList + '&hq_id=' + hq_id + '&customer_special=<?php echo $customer_special; ?>' + '&jb_id=<?php echo $jb_id; ?>' + '&f_act=');
ajaxRequestGet('../include/ajaxReqMap.php', 'cr_sid=' + crSidList + '&hq_id=' + hq_id + '&customer_special=<?php echo $customer_special; ?>' + '&jb_id=<?php echo $jb_id; ?>' + '&f_act=');
//console.log(couriers.markers.length);
for (var i = 0; i < couriers.markers.length; i++) {
//console.log(i);
tmpMarker = couriers.markers[i];
tmpUrl = tmpMarker.icon.url;
//console.log(tmpUrl);
tmpArr = tmpUrl.split("/");
//console.log(tmpArr[tmpArr.length - 1]);
if (tmpArr[tmpArr.length - 1].length > 12)
crSid = tmpArr[tmpArr.length - 1].substr(8, tmpArr[tmpArr.length - 1].length - 12);
else
crSid = tmpArr[tmpArr.length - 1].substr(0, tmpArr[tmpArr.length - 1].length - 4);
//console.log(crSid);
if (typeof prevRetValue[crSid] == "undefined") {
prevRetValue[crSid] = new Array(0);
}
if (prevRetValue[crSid][0] != retValue[crSid][0]) {
couriers.removeMarker(tmpMarker);
tmpMarker.feature.destroy();
tmpMarker.destroy();
setMarker(retValue[crSid][2], retValue[crSid][1], tmpUrl, size2.clone(), offset2.clone(), popupSize2.clone(), retValue[crSid][3], 'couriers');
prevRetValue[crSid][0] = retValue[crSid][0];
}
}
//console.log("setTimeout");
self.setTimeout("updateLayer('couriers')", 10000);
}
/********************************************************************************/
document.getElementById('map').setAttribute('style', 'width:' + (screen.availWidth - <?php echo $widthCorr; ?>) + '; height:' + (screen.availHeight - <?php echo $heightCorr; ?>) + '; vertical-align:middle;');
var lon = <?php echo $long; ?>;
var lat = <?php echo $lat; ?>;
var zoom = 11;
var map = new OpenLayers.Map('map',
{ controls:
[ new OpenLayers.Control.KeyboardDefaults(),
new OpenLayers.Control.MouseDefaults(),
new OpenLayers.Control.LayerSwitcher(),
new OpenLayers.Control.PanZoomBar(),
new OpenLayers.Control.ScaleLine(),
new OpenLayers.Control.MousePosition(),
new OpenLayers.Control.Attribution()
],
maxExtent: new OpenLayers.Bounds(-20037508.34,-20037508.34,20037508.34,20037508.34),
restrictedExtent: new OpenLayers.Bounds(-1337508.34, 4037508.34, 4837508.34, 9037508.34),
maxResolution: 156543.0399,
// minScale: 100000,
// maxScale: 10000000,
// numZoomLevels: 13,
units: 'm',
projection: new OpenLayers.Projection("EPSG:900913"),
displayProjection: new OpenLayers.Projection("EPSG:4326")
});
//var mapnik_layer = new OpenLayers.Layer.OSM.Mapnik("OSM Mapnik");
//var tah_layer = new OpenLayers.Layer.OSM.Osmarender("OSM Tiles@Home");
//var google_layer = new OpenLayers.Layer.Google("Google Streets", {'sphericalMercator': true});
// add Bing layer
//var yahoo_layer = new OpenLayers.Layer.Yahoo("Yahoo Street", {'sphericalMercator': true});
//map.addLayers([yahoo_layer, mapnik_layer, tah_layer]);
//map.addLayers([mapnik_layer, yahoo_layer]);
map.addLayers([
new OpenLayers.Layer.OSM("Google Streets",
["https://mt0.google.com/vt/lyrs=m&x=${x}&y=${y}&z=${z}", "https://mt1.google.com/vt/lyrs=m&x=${x}&y=${y}&z=${z}", "https://mt2.google.com/vt/lyrs=m&x=${x}&y=${y}&z=${z}", "https://mt3.google.com/vt/lyrs=m&x=${x}&y=${y}&z=${z}"],
{ attribution: '' } )
]);
map.addLayers([
new OpenLayers.Layer.OSM("Google Hybrid",
["https://mt0.google.com/vt/lyrs=s,h&x=${x}&y=${y}&z=${z}", "https://mt1.google.com/vt/lyrs=s,h&x=${x}&y=${y}&z=${z}", "https://mt2.google.com/vt/lyrs=s,h&x=${x}&y=${y}&z=${z}", "https://mt3.google.com/vt/lyrs=s,h&x=${x}&y=${y}&z=${z}"],
{ attribution: '' } )
]);
map.addLayers([
new OpenLayers.Layer.OSM("OSM Mapnik",
["https://a.tile.openstreetmap.org/${z}/${x}/${y}.png", "https://b.tile.openstreetmap.org/${z}/${x}/${y}.png", "https://c.tile.openstreetmap.org/${z}/${x}/${y}.png"],
{ attribution: "&copy; <a href=\"http://osm.org/copyright\">OpenStreetMap</a> contributors" } )
]);
map.addLayers([
new OpenLayers.Layer.OSM("OSM Mapnik german style",
["https://a.tile.openstreetmap.de/tiles/osmde/${z}/${x}/${y}.png", "https://b.tile.openstreetmap.de/tiles/osmde/${z}/${x}/${y}.png", "https://c.tile.openstreetmap.de/tiles/osmde/${z}/${x}/${y}.png"],
{ attribution: '<a href="http://www.openstreetmap.org/">Karte hergestellt aus OpenStreetMap-Daten</a> | Lizenz: <a rel="license" href="http://opendatacommons.org/licenses/odbl/">Open Database License (ODbL)</a>' } )
]);
map.setCenter (new OpenLayers.LonLat(lon, lat).transform(new OpenLayers.Projection("EPSG:4326"), map.getProjectionObject()), zoom);
//var newll = new OpenLayers.Layer.Text( "PLZs", { location:"zipcode.txt", projection: new OpenLayers.Projection("EPSG:4326") } );
//map.addLayer(newll);
//OpenLayers.Lang.setCode("de");
//alert (OpenLayers.Lang.getCode());
var central = new OpenLayers.Layer.Markers("Zentrale");
map.addLayer(central);
var couriers = new OpenLayers.Layer.Markers("Transporteure");
map.addLayer(couriers);
<?php
if ($jb_id != ""):
echo "var stations = new OpenLayers.Layer.Markers(\"Stationen\");";
echo "map.addLayer(stations);";
endif;
?>
var stocks = new OpenLayers.Layer.Markers("Läger");
map.addLayer(stocks);
var size1 = new OpenLayers.Size(28,28);
var popupSize1 = new OpenLayers.Size(60,20);
var offset1 = new OpenLayers.Pixel(-9, -28);
var size2 = new OpenLayers.Size(42,39);
var popupSize2 = new OpenLayers.Size(165,130);
var offset2 = new OpenLayers.Pixel(-6, -38);
var size3 = new OpenLayers.Size(28,28);
var popupSize3 = new OpenLayers.Size(140,118);
var offset3 = new OpenLayers.Pixel(-9, -28);
<?php echo $markers_javascript; ?>
central.setVisibility(false);
<?php
if ($jb_id != "" && $show_couriers == 0):
echo "couriers.setVisibility(false);";
endif;
?>
stocks.setVisibility(false);
<?php
if ($jb_id != ""):
echo "map.zoomToExtent(stations.getDataExtent());";
else:
echo "map.zoomToExtent(couriers.getDataExtent());";
endif;
?>
self.setTimeout("updateLayer('couriers')", 10000);
</script>
<script type="text/javascript">
function clearSearchCrSid() {
document.forms[0].searchCrSid.value='';
};
</script>
</div>
</div>
<!--
<form action="../locating/map_courier.php" method="post">
-->
<div>
<center>
&nbsp; <?php echo $errorMsg ?>
<!--
<input type="submit" value="Aktualisieren">
-->
<center>
</div>
<!--
</form>
-->
</div>
</div>
</body>
</html>

View File

@@ -0,0 +1,166 @@
<?php
include_once("../include/global.inc.php");
include_once ("../include/auth.inc.php");
// $hq_id = $HTTP_SESSION_VARS['hq_id'];
$hq_id = $_SESSION['hq_id'];
if ($hq_id == "") : $hq_id = $HTTP_SESSION_VARS['hq_id']; endif;
$hq_marker = "../images/marker_sb.png";
if ($hq_id >= 100)
$hq_marker = "../images/marker_ht.png";
$today = getdate();
//$start_time = date("YmdHis", mktime($today['hours'] - 24, $today['minutes'], $today['seconds'], $today['mon'], $today['mday'], $today['year']));
$start_time = date("Y-m-d H:i:s", mktime(0, 0, 0, $today['mon'], $today['mday'], $today['year']));
$lat = 0;
$long = 0;
list ($cr_sid) =
getHttpVars(array("cr_sid"));
//$markers_text = "point title description icon iconSize iconOffset\x0A";
$sqlquery = "SELECT hq_gps_long, hq_gps_lat FROM headquarters WHERE hq_id = '$hq_id'";
$markers_javascript = "";
$res = $db->query($sqlquery);
if (DB::isError($res))
die ("$PHP_SELF: '$sqlquery' : " . $res->getMessage());
if ($row = $res->fetch_assoc()):
$markers_javascript .= "var hq_icon = new OpenLayers.Icon('$hq_marker', size, offset);\n";
$markers_javascript .= "marker = new OpenLayers.Marker(new OpenLayers.LonLat(". $row["hq_gps_long"] . ", " . $row["hq_gps_lat"] . ").transform(new OpenLayers.Projection(\"EPSG:4326\"), map.getProjectionObject()), hq_icon);\n";
$markers_javascript .= "marker.events.register('mousedown', marker, function(evt) { alert('Zentrale'); OpenLayers.Event.stop(evt); });";
$markers_javascript .= "markers.addMarker(marker);\n";
// $markers_text .= $row["hq_gps_lat"] . "," . $row["hq_gps_long"] . " Zentrale honk $hq_marker 28,28 -10,-28\x0A";
$lat = $row["hq_gps_lat"];
$long = $row["hq_gps_long"];
endif;
$res->free();
$sqlquery = "SELECT cr_sid, cr_locationzipcode, cr_available, cr_availabletime, cr_gps_long, cr_gps_lat, cr_gps_time FROM courier WHERE hq_id = '$hq_id' AND cr_gps_time > '" . $start_time . "'"; //AND cr_available = 1 ORDER BY cr_gps_time, cr_sid";
if (trim($cr_sid) != "")
$sqlquery = "SELECT cr_sid, cr_locationzipcode, cr_availabletime, cr_gps_long, cr_gps_lat, cr_gps_time FROM courier WHERE cr_sid = '$cr_sid'";
$res = $db->query($sqlquery);
if (DB::isError($res))
die ("$PHP_SELF: '$sqlquery' : " . $res->getMessage());
$i = 1;
while ($row = $res->fetch_assoc()):
// $markers_text .= $row["cr_gps_lat"] . "," . $row["cr_gps_long"] . " " . $row["cr_sid"] . "honk " . $row["cr_gps_time"] . " ../images/marker_white.png 28,28 -10,-28\x0A";
$markers_javascript .= "var icon$i = new OpenLayers.Icon('../images/marker_white.png', size.clone(), offset.clone());\n";
$markers_javascript .= "marker = new OpenLayers.Marker(new OpenLayers.LonLat(". $row["cr_gps_long"] . ", " . $row["cr_gps_lat"] . ").transform(new OpenLayers.Projection(\"EPSG:4326\"), map.getProjectionObject()), icon" . $i++ . ");\n";
$markers_javascript .= "marker.events.register('mousedown', marker, function(evt) { alert('" . $row["cr_sid"] . "\\nFreimeldung: " . $row["cr_locationzipcode"] . " (" . $row["cr_availabletime"] . ")\\n" . "Ortungszeit: " . $row["cr_gps_time"] . "'); OpenLayers.Event.stop(evt); });";
$markers_javascript .= "markers.addMarker(marker);\n";
if (trim($cr_sid) != ""):
$lat = $row["cr_gps_lat"];
$long = $row["cr_gps_long"];
endif;
endwhile;
$res->free();
//$fname = "../temp/osm_text/" . $usr_id . $start_time . ".txt";
//if (!$handle = fopen($fname, "w"))
// die("Fehler beim schreibenden Zugriff auf '$fname'");
//if (!fwrite($handle, $markers_text))
// die ("Fehler beim Schreiben in '$fname'");
//fclose($handle);
?>
<html>
<head>
<title>KARTENDARSTELLUNG</title>
<link rel="stylesheet" type="text/css" href="../css/phoenix.css">
<!--
<script src="http://www.openlayers.org/api/OpenLayers.js"></script>
-->
<script src="../include/openlayers/OpenLayers.js"></script>
<script src="http://www.openstreetmap.org/openlayers/OpenStreetMap.js"></script>
<!--
<script src='http://maps.google.com/maps?file=api&amp;v=2&amp;key=ABQIAAAA3HdfrnxFAPWyY-aiJUxmqRTJQa0g3IQ9GZqIMmInSLzwtGDKaBQ0KYLwBEKSM7F9gCevcsIf6WPuIQ'></script>
<script src="http://api.maps.yahoo.com/ajaxymap?v=3.0&appid=euzuro-openlayers"></script>
-->
<noscript>
<center>
<b><br>JavaScript ist nicht verf&uuml;gbar. Bitte aktivieren Sie JavaScript<br><br>
in Ihrem Browser, damit diese Seite ordnungsgem&auml;&szlig; funktioniert!</b><br><br>
</center>
</noscript>
</head>
<body>
<div style="display: table; height: 100%; #position: relative; overflow: hidden; margin:auto;">
<div style=" #position: absolute; #top: 50%;display: table-cell; vertical-align: middle;">
<div style=" #position: relative; #top: -50%; border: 2px solid black;">
<div id="map" style="width:1007px; height:675px; vertical-align:middle;">
<script type="text/javascript">
var lon = <?php echo $long; ?>;
var lat = <?php echo $lat; ?>;
var zoom = 12;
var map = new OpenLayers.Map('map',
{ controls:
[ new OpenLayers.Control.KeyboardDefaults(),
new OpenLayers.Control.MouseDefaults(),
new OpenLayers.Control.LayerSwitcher(),
new OpenLayers.Control.PanZoomBar(),
new OpenLayers.Control.ScaleLine(),
new OpenLayers.Control.MousePosition(),
new OpenLayers.Control.Attribution()
],
maxExtent: new OpenLayers.Bounds(-20037508.34,-20037508.34,20037508.34,20037508.34),
restrictedExtent: new OpenLayers.Bounds(-1337508.34, 4037508.34, 4837508.34, 9037508.34),
maxResolution: 156543.0399,
// minScale: 100000,
// maxScale: 10000000,
// numZoomLevels: 13,
units: 'm',
projection: new OpenLayers.Projection("EPSG:900913"),
displayProjection: new OpenLayers.Projection("EPSG:4326")
});
var mapnik_layer = new OpenLayers.Layer.OSM.Mapnik("OSM Mapnik");
//var tah_layer = new OpenLayers.Layer.OSM.Osmarender("OSM Tiles@Home");
//var google_layer = new OpenLayers.Layer.Google("Google Streets", {'sphericalMercator': true});
//var yahoo_layer = new OpenLayers.Layer.Yahoo("Yahoo Street", {'sphericalMercator': true});
//map.addLayers([yahoo_layer, mapnik_layer, tah_layer]);
//map.addLayers([mapnik_layer, yahoo_layer]);
map.addLayers([mapnik_layer]);
map.setCenter (new OpenLayers.LonLat(lon, lat).transform(new OpenLayers.Projection("EPSG:4326"), map.getProjectionObject()), zoom);
//var newl = new OpenLayers.Layer.Text( "Fahrzeuge", { location:"<?php echo "$fname"; ?>", projection: new OpenLayers.Projection("EPSG:4326") } );
//map.addLayer(newl);
//var newll = new OpenLayers.Layer.Text( "PLZs", { location:"zipcode.txt", projection: new OpenLayers.Projection("EPSG:4326") } );
//map.addLayer(newll);
//OpenLayers.Lang.setCode("de");
//alert (OpenLayers.Lang.getCode());
var markers = new OpenLayers.Layer.Markers("Marker");
map.addLayer(markers);
//var size = new OpenLayers.Size(10,17);
//var offset = new OpenLayers.Pixel(-(size.w/2), -size.h);
//var icon = new OpenLayers.Icon('http://boston.openguides.org/markers/AQUA.png', size, offset);
var size = new OpenLayers.Size(28,28);
var offset = new OpenLayers.Pixel(-10, -28);
<?php echo $markers_javascript; ?>
//10,20 my orange title my orange description
//2,4 my aqua title my aqua description
//42,-71 my purple title my purple description<br/>is great. http://www.openlayers.org/api/img/zoom-world-mini.png
</script>
</div>
</div>
</div>
</div>
</body>
</html>

447
html/locating/map_pzm.php Normal file

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,119 @@
<?php
// Tobedone:
// - Adressen checken ob sie von Google Maps gefunden wurden
// - Problem, wenn Reihenfolge nicht eingehalten (Station in der Mitte unerledigt, die davor und danach jedoch schon erledigt)
include_once("../include/caglobal.inc.php");
include_once("../include/ranking.inc.php");
$country_codes = array(
"AL" => "Albania",
"AT" => "Austria",
"BE" => "Belgium",
"BG" => "Bulgaria",
"CH" => "Switzerland",
"CZ" => "Czech Republic",
"DE" => "Germany",
"DK" => "Denmark",
"ES" => "Spain",
"FI" => "Finland",
"FR" => "France",
"GB" => "United Kingdom",
"GR" => "Greece",
"HR" => "Croatia",
"HU" => "Hungary",
"IE" => "Ireland",
"IS" => "Iceland",
"IT" => "Italy",
"LI" => "Liechtenstein",
"LT" => "Lithuania",
"LU" => "Luxembourg",
"LV" => "Latvia",
"MC" => "Monaco",
"MK" => "Macedonia",
"NL" => "Netherlands",
"NO" => "Norway",
"PL" => "Poland",
"PT" => "Portugal",
"RO" => "Romania",
"SE" => "Sweden",
"SI" => "Slovenia",
"SK" => "Slovakia",
"UA" => "Ukraine");
function showInGoogleMaps($jb_id) {
global $usr_id, $country_codes;
// gespeicherte Job-Daten holen
list($hq_id, $cr_id, $cr_sid) = getFieldsValueFromId("job", "jb_id", $jb_id, array("hq_id", "cr_id", "cr_sid"));
// if ($hq_id != 3 && $hq_id != 2)
// return "";
$debug_text = "\$cr_id = " . $cr_id . ", \$cr_sid = " . $cr_sid . "\n";
$points = "";
$points_txt = "";
if ($cr_id != 0) {
$locatingStateArray = checkLocatingState($cr_id);
$debug_text .= "\$locatingStateArray = " . json_encode($locatingStateArray) . "\n";
if ($locatingStateArray[0] == "0") {
$points = "/" . $locatingStateArray[2] . "," . $locatingStateArray[1];
$points_txt = "(" . $locatingStateArray[2] . ", " . $locatingStateArray[1] . ")";
}
}
$debug_text .= "\$points = " . $points . "\n";
$i = 1;
$prevStopMap = "";
$prevStopText = "";
do {
$tourFound = 0;
// gespeicherte Tour-Daten holen
if (existsEntry("tour", array("jb_id", $jb_id, "tr_sort", $i))) {
$tourFound = 1;
list($csc_id, $tr_comp, $tr_person, $ad_street, $tr_hsno,
$ad_zipcode, $ad_city, $ad_country, $tr_remark, $tr_status, $tr_ware_from_to, $tr_commission_no, $tr_mediationarea_id, $tr_status, $tr_sign, $tr_signname, $tr_finishtime, $tr_id) =
getTourData($jb_id, $i, "tour");
$debug_text .= "\$tr_sort = " . $i . ", \$tr_status = " . $tr_status . "\n";
$country_code = $country_codes[($ad_country == "D" ? "DE" : $ad_country)];
if ($country_code == "Germany")
$country_code = "";
$endStopMap = "/" . str_replace("/", "%2F", my_str_check($ad_street)) . " " . str_replace("/", "%2F", $tr_hsno) . ", " . str_replace("/", "%2F", $ad_zipcode) . " " .
str_replace("/", "%2F", my_str_check($ad_city)) . ($country_code == "" ? "" : "," . $country_code);
$endStopText = my_str_check($ad_street) . " " . $tr_hsno . ", " . ($country_code == "" ? "" : $country_code . " ") . $ad_zipcode . " " . my_str_check($ad_city);
if ($tr_status == 1 && $points == "") {
$prevStopMap = $endStopMap;
$prevStopText = $endStopText;
}
$i++;
}
} while ($tourFound == 1 && $tr_status == 1);
$debug_text .= "\$prevStopMap = " . $prevStopMap . "\n";
$debug_text .= "\$endStopMap = " . $endStopMap . "\n";
$retStr = "";
if (($points != "" || $prevStopMap != "") && $endStopMap != "") {
$points .= $prevStopMap . $endStopMap;
$points_txt .= $prevStopText . " &minus;&gt; " . $endStopText;
$retStr = "<a href=\"https://www.google.de/maps/dir" . $points . "/" . "\" target=\"_blank\">" . $points_txt . "</a>";
} elseif ($points == "" && $prevStopMap == "") {
$retStr .= "<i>Keine&nbsp;aktuellen&nbsp;GPS&minus;Daten&nbsp;von&nbsp;" . $cr_sid . "&nbsp;verfügbar&nbsp;und&nbsp;erste&nbsp;Station&nbsp;noch&nbsp;nicht&nbsp;erledigt</i>";
} elseif ($endStopMap == "") {
$retStr .= "<i>Keine&nbsp;unerledigte&nbsp;Station&nbsp;mehr&nbsp;vorhanden</i>";
}
$debug_text .= "\$retStr = " . $retStr . "\n";
writeLog_showInGoogleMaps("\$jb_id = " . $jb_id . ", \$usr_id = " . $usr_id . "\n" . $debug_text);
return $retStr;
}
function writeLog_showInGoogleMaps($log_text) {
$today = getdate();
// echo $log_text . "\n"; die();
$fileHandle = @fopen("../log/showInGoogleMaps_" . $today['year'] . sprintf("%02d", $today['mon']) . ".log", 'a');
@fwrite($fileHandle, "[" . date("Y-m-d H:i:s") . "] " . $log_text . "\n");
@fclose($fileHandle);
return;
}
?>

File diff suppressed because it is too large Load Diff