Merged vue-client into master

This commit is contained in:
Sascha L. Teichmann 2022-03-07 10:40:45 +01:00
commit ab5400881b
41 changed files with 6782 additions and 3366 deletions

View File

@ -43,6 +43,8 @@ the map has to be pre-rendered with **mtseeder**.
it makes sense to do only small updates on pre-calculated images instead of generating it makes sense to do only small updates on pre-calculated images instead of generating
the map entirely on the fly. the map entirely on the fly.
* [Web-Map-Client](https://bitbucket.org/s_l_teichmann/mtsatellite/src/master/cmd/mtwebmapper/client) Web map application showing the base map of the minetest world and other in the browser.
This is Free Software under the terms of the MIT license. This is Free Software under the terms of the MIT license.
See [LICENSE](LICENSE) file for details. See [LICENSE](LICENSE) file for details.
(c) 2014 by Sascha L. Teichmann (c) 2014 by Sascha L. Teichmann

View File

@ -0,0 +1,2 @@
VUE_APP_WEBSOCKET_URL=ws://localhost:8080/socket
VUE_APP_TITLE=Demo World

23
cmd/mtwebmapper/client/.gitignore vendored Normal file
View File

@ -0,0 +1,23 @@
.DS_Store
node_modules
/dist
# local env files
.env.local
.env.*.local
# Log files
npm-debug.log*
yarn-debug.log*
yarn-error.log*
pnpm-debug.log*
# Editor directories and files
.idea
.vscode
*.suo
*.ntvs*
*.njsproj
*.sln
*.sw?

View File

@ -0,0 +1,31 @@
# Minetest Web-Map-Client
The web map client for mtsatellite is build as vue app using vuetify and leaflet as frameworks.
The following commands are all you need to set this application up.
## Project setup
```
yarn install
```
### Compiles and hot-reloads for development
```
yarn serve
```
### Compiles and minifies for production
```
yarn build
```
The result of this command is a ```dist``` folder containing the minified version. To use this in production, copy or move the folder to the location of your choice to serve the app.
### Lints and fixes files
```
yarn lint
```
### Customize configuration
To configure the backend websocket URL and the app title adjust the entries in the ```.env``` file.
See [Configuration Reference](https://cli.vuejs.org/config/).

View File

@ -0,0 +1,5 @@
module.exports = {
"presets": [
"@vue/cli-plugin-babel/preset"
]
}

View File

@ -0,0 +1,19 @@
{
"compilerOptions": {
"target": "es5",
"module": "esnext",
"baseUrl": "./",
"moduleResolution": "node",
"paths": {
"@/*": [
"src/*"
]
},
"lib": [
"esnext",
"dom",
"dom.iterable",
"scripthost"
]
}
}

View File

@ -0,0 +1,54 @@
{
"name": "Minetest-Web-Mapper",
"version": "0.1.0",
"private": true,
"scripts": {
"serve": "vue-cli-service serve",
"build": "vue-cli-service build",
"lint": "vue-cli-service lint"
},
"dependencies": {
"@babel/polyfill": "^7.4.4",
"core-js": "^3.8.3",
"leaflet": "^1.7.1",
"leaflet.coordinates": "^0.1.5",
"vue": "^2.6.14",
"vue2-leaflet": "^2.7.1",
"vue2-leaflet-markercluster": "^3.1.0",
"vuetify": "^2.6.0",
"vuex": "^3.6.2"
},
"devDependencies": {
"@babel/core": "^7.12.16",
"@babel/eslint-parser": "^7.12.16",
"@fortawesome/fontawesome-free": "^6.0.0",
"@vue/cli-plugin-babel": "~5.0.0",
"@vue/cli-plugin-eslint": "~5.0.0",
"@vue/cli-plugin-vuex": "~5.0.0",
"@vue/cli-service": "~5.0.0",
"eslint": "^7.32.0",
"eslint-plugin-vue": "^8.0.3",
"vue-cli-plugin-vuetify": "~2.4.6",
"vue-template-compiler": "^2.6.14"
},
"eslintConfig": {
"root": true,
"env": {
"node": true
},
"extends": [
"plugin:vue/essential",
"eslint:recommended"
],
"parserOptions": {
"parser": "@babel/eslint-parser"
},
"rules": {}
},
"browserslist": [
"> 1%",
"last 2 versions",
"not dead",
"not ie <= 10"
]
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.2 KiB

View File

@ -0,0 +1,18 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width,initial-scale=1.0">
<link rel="icon" href="<%= BASE_URL %>favicon.ico">
<title><%= VUE_APP_TITLE %></title>
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Roboto:100,300,400,500,700,900">
</head>
<body>
<noscript>
<strong>We're sorry but <%= htmlWebpackPlugin.options.title %> doesn't work properly without JavaScript enabled. Please enable it to continue.</strong>
</noscript>
<div id="app"></div>
<!-- built files will be auto injected -->
</body>
</html>

View File

@ -0,0 +1,138 @@
<template>
<v-app dark>
<v-navigation-drawer
v-model="drawer"
:clipped="true"
fixed
app
>
<v-list>
<v-list-item>
<v-list-item-action>
<v-checkbox v-model="playersLayer"></v-checkbox>
</v-list-item-action>
<v-list-item-content>
<v-list-item-title>Players</v-list-item-title>
</v-list-item-content>
</v-list-item>
</v-list>
</v-navigation-drawer>
<v-app-bar :clipped-left="true" fixed app>
<v-app-bar-nav-icon @click.stop="drawer = !drawer" />
<v-toolbar-title v-text="title" />
<v-spacer />
<v-btn icon @click.stop="refreshContent">
<v-icon v-if="!autoUpdate">fa-refresh</v-icon>
</v-btn>
<v-btn icon @click.stop="autoUpdate = !autoUpdate">
<v-icon v-if="!autoUpdate">fa-play</v-icon>
<v-icon v-else>fa-pause</v-icon>
</v-btn>
</v-app-bar>
<v-main>
<MapView />
</v-main>
<v-footer :absolute="!fixed" app>
<span>&copy; {{ new Date().getFullYear() }}</span>
<v-spacer />
<span>X: {{coordinates[0]}} - Y: {{coordinates[1]}}</span>
</v-footer>
</v-app>
</template>
<script>
import MapView from './components/MapView.vue'
import {mapState} from 'vuex';
export default {
name: 'App',
components: {
MapView
},
data() {
return {
drawer: false,
fixed: false,
title: process.env.VUE_APP_TITLE,
}
},
computed: {
...mapState({
players: state => state.players,
}),
autoUpdate: {
get() {
return this.$store.state.autoUpdate;
},
set(value) {
if (value) {
this.$store.dispatch("runAutoUpdate")
}
else {
this.$store.dispatch("stopAutoUpdate")
}
this.$store.commit("setAutoUpdate", value);
}
},
coordinates() {
return this.$store.state.coordinates;
},
playersLayer: {
get() {
return this.$store.state.playersLayer;
},
set(value) {
this.$store.commit("updatePlayersLayer", value)
}
},
buildingsLayer: {
get() {
return this.$store.state.buildingsLayer;
},
set(value) {
this.$store.commit("updateBuildingsLayer", value)
}
},
poiLayer: {
get() {
return this.$store.state.poiLayer;
},
set(value) {
this.$store.commit("updatePoiLayer", value)
}
},
travelnetLayer: {
get() {
return this.$store.state.travelnetLayer;
},
set(value) {
this.$store.commit("updateTravelnetLayer", value)
}
},
otherLayer: {
get() {
return this.$store.state.otherLayer;
},
set(value) {
this.$store.commit("updateOtherLayer", value)
}
}
},
mounted() {
fetch("players").then(response => response.json().then((data) => {
this.$store.commit("setPlayers", data);
}))
},
methods: {
refreshContent() {
this.$store.dispatch("manualUpdate");
}
}
}
</script>
<style>
html { overflow-y: auto !important; }
.v-navigation-drawer {
z-index: 1001 !important;
}
</style>

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

View File

@ -0,0 +1,86 @@
<template>
<v-container fluid style="height: 100%; padding: 0px">
<l-map @mousemove="update" ref="map" style="height: 100%" :zoom="zoom" :center="center" :worldCopyJump="worldCopyJump" :crs="crs" :options="mapOptions">
<l-tile-layer ref="baseLayer" :url="url" :attribution="attribution" :tms="tms" continuousWorld="false" minZoom=0 :noWrap="noWrap" :options="layerOptions"></l-tile-layer>
<div v-if="playersLayer">
<l-marker v-for="p in players" :key="p.name" :lat-lng="flipCoordinates(p.geometry.coordinates)" :icon="iconPlayer">
<l-popup>{{p.properties.name}}</l-popup>
</l-marker>
</div>
</l-map>
</v-container>
</template>
<script>
import L from 'leaflet';
import {mapState} from 'vuex';
L.Projection.NoWrap = {
project(latlng) {
return new L.Point(latlng.lat, latlng.lng);
},
unproject(point) {
return new L.LatLng(point.x, point.y, true);
},
bounds: L.bounds(L.point(-30928.0,30928.0),L.point(30928.0, -30928.0))
};
const ownCRS = L.CRS.Direct = L.Util.extend({}, L.CRS, {
code: 'Direct',
projection: L.Projection.NoWrap,
transformation: new L.Transformation(1.0/65536, 30928.0/65536, -1.0/65536, 34608.0/65536)
});
export default {
name: 'MapView',
data: () => {
return {
mapOptions: {
fadeAnimation: false
},
layerOptions: {
unloadInvisibleTiles: true
},
socket: null,
url: 'map/{z}/{x}/{y}.png',
zoom: 3,
noWrap: true,
center: [0,0],
worldCopyJump: false,
crs: ownCRS,
tms: true,
attribution: process.env.VUE_APP_TITLE,
features: [],
iconPlayer: new L.Icon({
iconUrl: require('@/assets/marker-player.png'),
iconSize: [25, 41],
iconAnchor: [12, 41],
popupAnchor: [1, -34],
}),
}
},
computed: {
players() {
return this.$store.state.players;
},
...mapState({
autoUpdate: state => state.autoUpdate,
playersLayer: state => state.playersLayer,
}),
},
methods: {
update(evt) {
this.$store.commit('updateCoordinates', [evt.latlng.lat, evt.latlng.lng])
},
flipCoordinates(pos) {
return [pos[1], pos[0]];
}
},
}
</script>
<style>
.leaflet-touch .leaflet-bar a {
color: #f5f5f5;
background-color: #424242;
}
</style>

View File

@ -0,0 +1,14 @@
import Vue from 'vue'
import App from './App.vue'
import vuetify from './plugins/vuetify'
import './plugins/leaflet'
import '@babel/polyfill'
import store from './store'
Vue.config.productionTip = false
new Vue({
vuetify,
store,
render: h => h(App)
}).$mount('#app')

View File

@ -0,0 +1,12 @@
import Vue from 'vue';
import { LMap, LTileLayer, LMarker, LPopup } from 'vue2-leaflet';
import Vue2LeafletMarkerCluster from 'vue2-leaflet-markercluster'
import 'leaflet/dist/leaflet.css';
import "leaflet.markercluster/dist/MarkerCluster.css";
import "leaflet.markercluster/dist/MarkerCluster.Default.css";
Vue.component('l-map', LMap);
Vue.component('l-tile-layer', LTileLayer);
Vue.component('l-marker', LMarker);
Vue.component('l-popup', LPopup);
Vue.component('l-marker-cluster', Vue2LeafletMarkerCluster);

View File

@ -0,0 +1,27 @@
import Vue from 'vue';
import Vuetify from 'vuetify';
import 'vuetify/dist/vuetify.min.css';
import colors from 'vuetify/es5/util/colors'
import '@fortawesome/fontawesome-free/css/all.css'
Vue.use(Vuetify);
export default new Vuetify({
icons: {
iconfont: 'fa',
},
theme: {
dark: true,
themes: {
dark: {
primary: colors.blue.darken2,
accent: colors.grey.darken3,
secondary: colors.amber.darken3,
info: colors.teal.lighten1,
warning: colors.amber.base,
error: colors.deepOrange.accent4,
success: colors.green.accent3,
},
},
},
});

View File

@ -0,0 +1,188 @@
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
export default new Vuex.Store({
state: {
socket: null,
autoUpdate: false,
coordinates: [0, 0],
playersLayer: true,
buildingsLayer: true,
poiLayer: true,
travelnetLayer: true,
otherLayer: true,
players: []
},
mutations: {
updateCoordinates(state, value) {
state.coordinates = value;
},
setAutoUpdate(state, value) {
state.autoUpdate = value
},
updatePlayersLayer(state, value) {
state.playersLayer = value;
},
updateBuildingsLayer(state, value) {
state.buildingsLayer = value;
},
updatePoiLayer(state, value) {
state.poiLayer = value;
},
updateTravelnetLayer(state, value) {
state.travelnetLayer = value;
},
updateOtherLayer(state, value) {
state.otherLayer = value;
},
setPlayers(state, value) {
state.players = value;
},
setPlayerState(state, value) {
const p = state.players.find(p => p.name === value.name)
p.online = value.state;
}
},
actions: {
stopAutoUpdate: function({ state }) {
if (state.socket) {
var s = state.socket;
state.socket = null;
s.close();
}
},
manualUpdate: function({commit}) {
var tiles = document.getElementsByTagName("img");
for (var i = 0; i < tiles.length; i++) {
var img = tiles[i];
var cl = img.getAttribute("class");
if (cl.indexOf("leaflet-tile-loaded") >= 0) {
var src = img.src;
var idx = src.lastIndexOf("#");
if (idx >= 0) {
src = src.substring(0, idx);
}
img.src = src + "#" + Math.random();
}
}
fetch("players").then(response => response.json().then((data) => {
commit("setPlayers", data);
}));
},
runAutoUpdate: function({ commit, state, dispatch}) {
var me = this;
state.socket = new WebSocket(process.env.VUE_APP_WEBSOCKET_URL);
state.socket.onerror = function() {
commit('setAutoUpdate', false)
dispatch('stopAutoUpdate');
};
state.socket.onclose = function() {
commit('setAutoUpdate', false)
state.socket = null;
}
state.socket.onopen = function() {
// Sending pings every 5 secs to keep connection alive.
var heartbeat = function() {
if (heartbeat && me.socket) {
me.socket.send("PING");
setTimeout(heartbeat, 8000);
} else {
// Prevent sending pings to re-opened sockets.
heartbeat = null;
}
};
setTimeout(heartbeat, 8000);
};
state.socket.onmessage = function(evt) {
var json = evt.data;
if (!(typeof json === "string")) {
return;
}
var msg;
try {
msg = JSON.parse(json);
}
catch (err) {
return;
}
if (msg.players) {
commit('setPlayers', msg.players);
}
var tilesData = msg.tiles;
if (!tilesData) {
return;
}
var invalidate = function(td) {
var pyramid = new Array(9);
var last = new Object();
pyramid[8] = last;
for (var i = 0; i < td.length; i++) {
var xz = td[i];
last[xz.X + "#" + xz.Z] = xz;
}
for (var p = 7; p >= 0; p--) {
var prev = pyramid[p+1];
var curr = new Object();
pyramid[p] = curr;
for (var k in prev) {
if (Object.prototype.hasOwnProperty.call(prev, k)) {
var oxz = prev[k];
var nxz = { X: oxz.X >> 1, Z: oxz.Z >> 1 };
curr[nxz.X + "#" + nxz.Z] = nxz;
}
}
}
return function(x, y, z) {
if (y > 8) {
x >>= y - 8;
z >>= y - 8;
y = 8;
}
var level = pyramid[y];
var k = x + "#" + z;
return Object.prototype.hasOwnProperty.call(level, k);
};
} (tilesData);
var tiles = document.getElementsByTagName('img');
var re = /\/map\/([0-9]+)\/([0-9]+)\/([0-9]+).*/;
for (var i = 0; i < tiles.length; i++) {
var img = tiles[i];
var cl = img.getAttribute('class');
if (cl.indexOf('leaflet-tile-loaded') < 0) {
continue;
}
var src = img.src;
var coord = src.match(re);
if (coord == null) {
continue;
}
var y = parseInt(coord[1]);
var x = parseInt(coord[2]);
var z = parseInt(coord[3]);
if (invalidate(x, y, z)) {
var idx = src.lastIndexOf('#');
if (idx >= 0) {
src = src.substring(0, idx);
}
img.src = src + '#' + Math.random();
}
}
};
}
}
})

View File

@ -0,0 +1,4 @@
const { defineConfig } = require('@vue/cli-service')
module.exports = defineConfig({
transpileDependencies: true
})

File diff suppressed because it is too large Load Diff

View File

@ -1 +0,0 @@
.leaflet-control-coordinates{background-color:#D8D8D8;background-color:rgba(255,255,255,.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}

File diff suppressed because it is too large Load Diff

Binary file not shown.

Before

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 30 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 535 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 40 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 65 KiB

View File

@ -1,124 +0,0 @@
/*
Author: L. Voogdt
License: MIT
Version: 1.0
*/
/* Marker setup */
.awesome-marker {
background: url('images/markers-soft.png') no-repeat 0 0;
width: 35px;
height: 46px;
position:absolute;
left:0;
top:0;
display: block;
text-align: center;
}
.awesome-marker-shadow {
background: url('images/markers-shadow.png') no-repeat 0 0;
width: 36px;
height: 16px;
}
/* Retina displays */
@media (min--moz-device-pixel-ratio: 1.5),(-o-min-device-pixel-ratio: 3/2),
(-webkit-min-device-pixel-ratio: 1.5),(min-device-pixel-ratio: 1.5),(min-resolution: 1.5dppx) {
.awesome-marker {
background-image: url('images/markers-soft@2x.png');
background-size: 720px 46px;
}
.awesome-marker-shadow {
background-image: url('images/markers-shadow@2x.png');
background-size: 35px 16px;
}
}
.awesome-marker i {
color: #333;
margin-top: 10px;
display: inline-block;
font-size: 14px;
}
.awesome-marker .icon-white {
color: #fff;
}
/* Colors */
.awesome-marker-icon-red {
background-position: 0 0;
}
.awesome-marker-icon-darkred {
background-position: -180px 0;
}
.awesome-marker-icon-lightred {
background-position: -360px 0;
}
.awesome-marker-icon-orange {
background-position: -36px 0;
}
.awesome-marker-icon-beige {
background-position: -396px 0;
}
.awesome-marker-icon-green {
background-position: -72px 0;
}
.awesome-marker-icon-darkgreen {
background-position: -252px 0;
}
.awesome-marker-icon-lightgreen {
background-position: -432px 0;
}
.awesome-marker-icon-blue {
background-position: -108px 0;
}
.awesome-marker-icon-darkblue {
background-position: -216px 0;
}
.awesome-marker-icon-lightblue {
background-position: -468px 0;
}
.awesome-marker-icon-purple {
background-position: -144px 0;
}
.awesome-marker-icon-darkpurple {
background-position: -288px 0;
}
.awesome-marker-icon-pink {
background-position: -504px 0;
}
.awesome-marker-icon-cadetblue {
background-position: -324px 0;
}
.awesome-marker-icon-white {
background-position: -574px 0;
}
.awesome-marker-icon-gray {
background-position: -648px 0;
}
.awesome-marker-icon-lightgray {
background-position: -612px 0;
}
.awesome-marker-icon-black {
background-position: -682px 0;
}

View File

@ -1,478 +0,0 @@
/* required styles */
.leaflet-map-pane,
.leaflet-tile,
.leaflet-marker-icon,
.leaflet-marker-shadow,
.leaflet-tile-pane,
.leaflet-tile-container,
.leaflet-overlay-pane,
.leaflet-shadow-pane,
.leaflet-marker-pane,
.leaflet-popup-pane,
.leaflet-overlay-pane svg,
.leaflet-zoom-box,
.leaflet-image-layer,
.leaflet-layer {
position: absolute;
left: 0;
top: 0;
}
.leaflet-container {
overflow: hidden;
-ms-touch-action: none;
}
.leaflet-tile,
.leaflet-marker-icon,
.leaflet-marker-shadow {
-webkit-user-select: none;
-moz-user-select: none;
user-select: none;
-webkit-user-drag: none;
}
.leaflet-marker-icon,
.leaflet-marker-shadow {
display: block;
}
/* map is broken in FF if you have max-width: 100% on tiles */
.leaflet-container img {
max-width: none !important;
}
/* stupid Android 2 doesn't understand "max-width: none" properly */
.leaflet-container img.leaflet-image-layer {
max-width: 15000px !important;
}
.leaflet-tile {
filter: inherit;
visibility: hidden;
}
.leaflet-tile-loaded {
visibility: inherit;
}
.leaflet-zoom-box {
width: 0;
height: 0;
}
/* workaround for https://bugzilla.mozilla.org/show_bug.cgi?id=888319 */
.leaflet-overlay-pane svg {
-moz-user-select: none;
}
.leaflet-tile-pane { z-index: 2; }
.leaflet-objects-pane { z-index: 3; }
.leaflet-overlay-pane { z-index: 4; }
.leaflet-shadow-pane { z-index: 5; }
.leaflet-marker-pane { z-index: 6; }
.leaflet-popup-pane { z-index: 7; }
.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: 7;
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,
.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-tile-loaded,
.leaflet-fade-anim .leaflet-map-pane .leaflet-popup {
opacity: 1;
}
.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,
.leaflet-touching .leaflet-zoom-animated {
-webkit-transition: none;
-moz-transition: none;
-o-transition: none;
transition: none;
}
.leaflet-zoom-anim .leaflet-zoom-hide {
visibility: hidden;
}
/* cursors */
.leaflet-clickable {
cursor: pointer;
}
.leaflet-container {
cursor: -webkit-grab;
cursor: -moz-grab;
}
.leaflet-popup-pane,
.leaflet-control {
cursor: auto;
}
.leaflet-dragging .leaflet-container,
.leaflet-dragging .leaflet-clickable {
cursor: move;
cursor: -webkit-grabbing;
cursor: -moz-grabbing;
}
/* 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-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;
}
/* 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: content-box;
box-sizing: content-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;
}
.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 {
margin: 0 auto;
width: 40px;
height: 20px;
position: relative;
overflow: hidden;
}
.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;
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;
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;
}

View File

@ -1,152 +0,0 @@
<!DOCTYPE html>
<html>
<head>
<title>Minetest demo map</title>
<meta charset="utf-8" />
<link rel="stylesheet" href="css/leaflet.css" />
<link rel="stylesheet" href="css/Leaflet.Coordinates-0.1.4.css" />
<link rel="stylesheet" href="css/font-awesome.css" />
<link rel="stylesheet" href="css/leaflet.awesome-markers.css" />
<style type="text/css">
body {
height: 100%;
}
#map {
display: block;
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
background-color: #111111;
}
.leaflet-container {
cursor: crosshair;
}
.leaflet-control-coordinates,
.leaflet-control-layers {
box-shadow: 0 1px 3px rgba(0,0,0,0.3);
background-color:rgba(255,255,255,.85);
}
.awesome-marker i {
font-size: 18px;
margin-left: -1px;
}
</style>
</head>
<body>
<div id="map"></div>
<script src="js/leaflet.js"></script>
<script src="js/Leaflet.Coordinates-0.1.4.min.js"></script>
<script src="js/easy-button.js"></script>
<script src="js/auto-update.js"></script>
<script type="text/javascript" src="js/leaflet-hash.js"></script>
<script type="text/javascript" src="js/leaflet.ajax.js"></script>
<script type="text/javascript" src="js/leaflet.awesome-markers.js"></script>
<script>
var useWebsocket = true; // Set to true if you want websocket support
L.Projection.NoWrap = {
project: function (latlng) {
return new L.Point(latlng.lat, latlng.lng);
},
unproject: function (point, unbounded) {
return new L.LatLng(point.x, point.y, true);
}
};
L.CRS.Direct = L.Util.extend({}, L.CRS, {
code: 'Direct',
projection: L.Projection.NoWrap,
transformation: new L.Transformation(1.0/65536, 30928.0/65536, -1.0/65536, 34608.0/65536)
});
var world = new L.tileLayer('map/{z}/{x}/{y}.png', {
minZoom: 0,
maxZoom: 16,
attribution: 'Demo world',
continuousWorld: false,
noWrap: true,
tms: true,
unloadInvisibleTiles: true
});
var players = L.geoJson.ajax('/players', {
pointToLayer: function(feature, latlng) {
return L.marker(latlng, {
icon: L.AwesomeMarkers.icon({
icon: 'male',
iconColor: 'black',
prefix: 'fa',
markerColor: 'orange'
}),
title: feature.properties.name
})
}
});
var rasterMaps = {
"A demo world": world,
};
var latest = world
var overlayMaps = {'Players': players};
var map = L.map('map', {
center: [0,0],
zoom: 3,
layers: [latest],
worldCopyJump: false,
crs: L.CRS.Direct});
L.control.coordinates({
position:"topright", //optional default "bootomright"
decimals:0, //optional default 4
decimalSeperator:".", //optional default "."
labelTemplateLat:"X: {y}", //optional default "Lat: {y}"
labelTemplateLng:"Y: {x}", //optional default "Lng: {x}"
enableUserInput:false, //optional default true
useDMS:false, //optional default false
useLatLngOrder: true //ordering of labels, default false-> lng-lat
}).addTo(map);
var manualUpdateControl;
if (useWebsocket && 'WebSocket' in window) {
L.autoUpdate('autoUpdate', function(pressed) {
var styleDec = manualUpdateControl.getContainer().style;
styleDec.visibility = pressed ? 'hidden' : 'visible';
},
players);
}
var layersControl = new L.Control.Layers(rasterMaps, overlayMaps, {collapsed: false});
map.addControl(layersControl);
manualUpdateControl = L.easyButton('fa-refresh',
function (){
var tiles = document.getElementsByTagName("img");
for (var i = 0; i < tiles.length; i++) {
var img = tiles[i];
var cl = img.getAttribute("class");
if (cl.indexOf("leaflet-tile-loaded") >= 0) {
var src = img.src;
var idx = src.lastIndexOf("#");
if (idx >= 0) {
src = src.substring(0, idx);
}
img.src = src + "#" + Math.random();
}
}
//map._resetView(map.getCenter(), map.getZoom(), false);
players.refresh("/players");
},
'Update view'
);
var hash = new L.Hash(map)
</script>
</body>
</html>

File diff suppressed because one or more lines are too long

View File

@ -1,187 +0,0 @@
L.Control.AutoUpdate = L.Control.extend({
options: {
position: 'topleft',
label: 'Automatic update',
layer: undefined
},
pressed: true,
onAdd: function() {
var container = L.DomUtil.create('div', 'leaflet-bar leaflet-control');
this.link = L.DomUtil.create('a', 'leaflet-bar-part', container);
this.iconStart = L.DomUtil.create('i', 'fa fa-play', this.link);
this.link.href = '#';
L.DomEvent.on(this.link, 'click', this.cbClick, this);
return container;
},
switchButtons: function() {
if (this.pressed) {
this.pressed = false;
this.iconStart.setAttribute('class', 'fa fa-pause');
this.autoUpdate();
} else {
this.pressed = true;
this.iconStart.setAttribute('class', 'fa fa-play');
this.stopUpdate();
}
},
cbClick: function (e) {
L.DomEvent.stopPropagation(e);
this.intendedFunction(this.pressed);
this.switchButtons();
},
intendedFunction: function() {
alert('no function selected');
},
stopUpdate: function() {
if (this.socket) {
var s = this.socket;
this.socket = null;
s.close();
}
},
autoUpdate: function() {
var me = this;
this.socket = new WebSocket('ws://' + window.location.host + '/ws');
this.socket.onerror = function(evt) {
me.stopUpdate();
me.switchButtons();
};
this.socket.onclose = function(evt) {
this.socket = null;
}
this.socket.onopen = function(evt) {
// Sending pings every 5 secs to keep connection alive.
var heartbeat = function() {
if (heartbeat && me.socket) {
me.socket.send("PING");
setTimeout(heartbeat, 8000);
} else {
// Prevent sending pings to re-opened sockets.
heartbeat = null;
}
};
setTimeout(heartbeat, 8000);
};
this.socket.onmessage = function(evt) {
var json = evt.data;
if (!(typeof json === "string")) {
return;
}
var msg;
try {
msg = JSON.parse(json);
}
catch (err) {
return;
}
if (msg.players) {
me.options.layer.clearLayers();
me.options.layer.addData(msg.players);
}
var tilesData = msg.tiles;
if (!tilesData) {
return;
}
var invalidate = function(td) {
var pyramid = new Array(9);
var last = new Object();
pyramid[8] = last;
for (var i = 0; i < td.length; i++) {
var xz = td[i];
last[xz.X + "#" + xz.Z] = xz;
}
for (var p = 7; p >= 0; p--) {
var prev = pyramid[p+1];
var curr = new Object();
pyramid[p] = curr;
for (var k in prev) {
if (prev.hasOwnProperty(k)) {
var oxz = prev[k];
var nxz = { X: oxz.X >> 1, Z: oxz.Z >> 1 };
curr[nxz.X + "#" + nxz.Z] = nxz;
}
}
}
return function(x, y, z) {
if (y > 8) {
x >>= y - 8;
z >>= y - 8;
y = 8;
}
var level = pyramid[y];
var k = x + "#" + z;
return level.hasOwnProperty(k);
};
} (tilesData);
var tiles = document.getElementsByTagName('img');
var re = /\/map\/([0-9]+)\/([0-9]+)\/([0-9]+).*/;
for (var i = 0; i < tiles.length; i++) {
var img = tiles[i];
var cl = img.getAttribute('class');
if (cl.indexOf('leaflet-tile-loaded') < 0) {
continue;
}
var src = img.src;
var coord = src.match(re);
if (coord == null) {
continue;
}
var y = parseInt(coord[1]);
var x = parseInt(coord[2]);
var z = parseInt(coord[3]);
if (invalidate(x, y, z)) {
var idx = src.lastIndexOf('#');
if (idx >= 0) {
src = src.substring(0, idx);
}
img.src = src + '#' + Math.random();
}
}
};
}
});
L.autoUpdate = function(cbLabel, cbFunc, layer, cbMap) {
var control = new L.Control.AutoUpdate();
if (cbLabel) {
control.options.label = cbLabel;
}
if (cbFunc) {
control.intendedFunction = cbFunc;
}
if (layer) {
control.options.layer = layer;
}
if (cbMap === '') {
return control;
}
else if (cbMap) {
cbMap.addControl(control);
}
else {
map.addControl(control);
}
return control;
};

View File

@ -1,48 +0,0 @@
L.Control.EasyButtons = L.Control.extend({
options: {
position: 'topleft',
title: '',
intentedIcon: 'fa-circle-o'
},
onAdd: function () {
var container = L.DomUtil.create('div', 'leaflet-bar leaflet-control');
this.link = L.DomUtil.create('a', 'leaflet-bar-part', container);
L.DomUtil.create('i', 'fa fa-lg ' + this.options.intentedIcon , this.link);
this.link.href = '#';
L.DomEvent.on(this.link, 'click', this._click, this);
this.link.title = this.options.title;
return container;
},
intendedFunction: function(){ alert('no function selected');},
_click: function (e) {
L.DomEvent.stopPropagation(e);
L.DomEvent.preventDefault(e);
this.intendedFunction();
},
});
L.easyButton = function( btnIcon , btnFunction , btnTitle , btnMap ) {
var newControl = new L.Control.EasyButtons;
if (btnIcon) newControl.options.intentedIcon = btnIcon;
if ( typeof btnFunction === 'function'){
newControl.intendedFunction = btnFunction;
}
if (btnTitle) newControl.options.title = btnTitle;
if ( btnMap == '' ){
// skip auto addition
} else if ( btnMap ) {
btnMap.addControl(newControl);
} else {
map.addControl(newControl);
}
return newControl;
};

View File

@ -1,162 +0,0 @@
(function(window) {
var HAS_HASHCHANGE = (function() {
var doc_mode = window.documentMode;
return ('onhashchange' in window) &&
(doc_mode === undefined || doc_mode > 7);
})();
L.Hash = function(map) {
this.onHashChange = L.Util.bind(this.onHashChange, this);
if (map) {
this.init(map);
}
};
L.Hash.parseHash = function(hash) {
if(hash.indexOf('#') === 0) {
hash = hash.substr(1);
}
var args = hash.split("/");
if (args.length == 3) {
var zoom = parseInt(args[0], 10),
lat = parseFloat(args[1]),
lon = parseFloat(args[2]);
if (isNaN(zoom) || isNaN(lat) || isNaN(lon)) {
return false;
} else {
return {
center: new L.LatLng(lat, lon),
zoom: zoom
};
}
} else {
return false;
}
};
L.Hash.formatHash = function(map) {
var center = map.getCenter(),
zoom = map.getZoom(),
precision = Math.max(0, Math.ceil(Math.log(zoom) / Math.LN2));
return "#" + [zoom,
center.lat.toFixed(precision),
center.lng.toFixed(precision)
].join("/");
},
L.Hash.prototype = {
map: null,
lastHash: null,
parseHash: L.Hash.parseHash,
formatHash: L.Hash.formatHash,
init: function(map) {
this.map = map;
// reset the hash
this.lastHash = null;
this.onHashChange();
if (!this.isListening) {
this.startListening();
}
},
removeFrom: function(map) {
if (this.changeTimeout) {
clearTimeout(this.changeTimeout);
}
if (this.isListening) {
this.stopListening();
}
this.map = null;
},
onMapMove: function() {
// bail if we're moving the map (updating from a hash),
// or if the map is not yet loaded
if (this.movingMap || !this.map._loaded) {
return false;
}
var hash = this.formatHash(this.map);
if (this.lastHash != hash) {
location.replace(hash);
this.lastHash = hash;
}
},
movingMap: false,
update: function() {
var hash = location.hash;
if (hash === this.lastHash) {
return;
}
var parsed = this.parseHash(hash);
if (parsed) {
this.movingMap = true;
this.map.setView(parsed.center, parsed.zoom);
this.movingMap = false;
} else {
this.onMapMove(this.map);
}
},
// defer hash change updates every 100ms
changeDefer: 100,
changeTimeout: null,
onHashChange: function() {
// throttle calls to update() so that they only happen every
// `changeDefer` ms
if (!this.changeTimeout) {
var that = this;
this.changeTimeout = setTimeout(function() {
that.update();
that.changeTimeout = null;
}, this.changeDefer);
}
},
isListening: false,
hashChangeInterval: null,
startListening: function() {
this.map.on("moveend", this.onMapMove, this);
if (HAS_HASHCHANGE) {
L.DomEvent.addListener(window, "hashchange", this.onHashChange);
} else {
clearInterval(this.hashChangeInterval);
this.hashChangeInterval = setInterval(this.onHashChange, 50);
}
this.isListening = true;
},
stopListening: function() {
this.map.off("moveend", this.onMapMove, this);
if (HAS_HASHCHANGE) {
L.DomEvent.removeListener(window, "hashchange", this.onHashChange);
} else {
clearInterval(this.hashChangeInterval);
}
this.isListening = false;
}
};
L.hash = function(map) {
return new L.Hash(map);
};
L.Map.prototype.addHash = function() {
this._hash = L.hash(this);
};
L.Map.prototype.removeHash = function() {
this._hash.removeFrom();
};
})(window);

View File

@ -1,740 +0,0 @@
;(function(){
/**
* Require the given path.
*
* @param {String} path
* @return {Object} exports
* @api public
*/
function require(path, parent, orig) {
var resolved = require.resolve(path);
// lookup failed
if (null == resolved) {
orig = orig || path;
parent = parent || 'root';
var err = new Error('Failed to require "' + orig + '" from "' + parent + '"');
err.path = orig;
err.parent = parent;
err.require = true;
throw err;
}
var module = require.modules[resolved];
// perform real require()
// by invoking the module's
// registered function
if (!module.exports) {
module.exports = {};
module.client = module.component = true;
module.call(this, module.exports, require.relative(resolved), module);
}
return module.exports;
}
/**
* Registered modules.
*/
require.modules = {};
/**
* Registered aliases.
*/
require.aliases = {};
/**
* Resolve `path`.
*
* Lookup:
*
* - PATH/index.js
* - PATH.js
* - PATH
*
* @param {String} path
* @return {String} path or null
* @api private
*/
require.resolve = function(path) {
if (path.charAt(0) === '/') path = path.slice(1);
var paths = [
path,
path + '.js',
path + '.json',
path + '/index.js',
path + '/index.json'
];
for (var i = 0; i < paths.length; i++) {
var path = paths[i];
if (require.modules.hasOwnProperty(path)) return path;
if (require.aliases.hasOwnProperty(path)) return require.aliases[path];
}
};
/**
* Normalize `path` relative to the current path.
*
* @param {String} curr
* @param {String} path
* @return {String}
* @api private
*/
require.normalize = function(curr, path) {
var segs = [];
if ('.' != path.charAt(0)) return path;
curr = curr.split('/');
path = path.split('/');
for (var i = 0; i < path.length; ++i) {
if ('..' == path[i]) {
curr.pop();
} else if ('.' != path[i] && '' != path[i]) {
segs.push(path[i]);
}
}
return curr.concat(segs).join('/');
};
/**
* Register module at `path` with callback `definition`.
*
* @param {String} path
* @param {Function} definition
* @api private
*/
require.register = function(path, definition) {
require.modules[path] = definition;
};
/**
* Alias a module definition.
*
* @param {String} from
* @param {String} to
* @api private
*/
require.alias = function(from, to) {
if (!require.modules.hasOwnProperty(from)) {
throw new Error('Failed to alias "' + from + '", it does not exist');
}
require.aliases[to] = from;
};
/**
* Return a require function relative to the `parent` path.
*
* @param {String} parent
* @return {Function}
* @api private
*/
require.relative = function(parent) {
var p = require.normalize(parent, '..');
/**
* lastIndexOf helper.
*/
function lastIndexOf(arr, obj) {
var i = arr.length;
while (i--) {
if (arr[i] === obj) return i;
}
return -1;
}
/**
* The relative require() itself.
*/
function localRequire(path) {
var resolved = localRequire.resolve(path);
return require(resolved, parent, path);
}
/**
* Resolve relative to the parent.
*/
localRequire.resolve = function(path) {
var c = path.charAt(0);
if ('/' == c) return path.slice(1);
if ('.' == c) return require.normalize(p, path);
// resolve deps by returning
// the dep in the nearest "deps"
// directory
var segs = parent.split('/');
var i = lastIndexOf(segs, 'deps') + 1;
if (!i) i = 0;
path = segs.slice(0, i + 1).join('/') + '/deps/' + path;
return path;
};
/**
* Check if module is defined at `path`.
*/
localRequire.exists = function(path) {
return require.modules.hasOwnProperty(localRequire.resolve(path));
};
return localRequire;
};
require.register("calvinmetcalf-setImmediate/lib/index.js", function(exports, require, module){
"use strict";
var types = [
require("./nextTick"),
require("./mutation"),
require("./postMessage"),
require("./messageChannel"),
require("./stateChange"),
require("./timeout")
];
var handlerQueue = [];
function drainQueue() {
var i = 0,
task,
innerQueue = handlerQueue;
handlerQueue = [];
/*jslint boss: true */
while (task = innerQueue[i++]) {
task();
}
}
var nextTick;
types.some(function (obj) {
var t = obj.test();
if (t) {
nextTick = obj.install(drainQueue);
}
return t;
});
var retFunc = function (task) {
var len, args;
if (arguments.length > 1 && typeof task === "function") {
args = Array.prototype.slice.call(arguments, 1);
args.unshift(undefined);
task = task.bind.apply(task, args);
}
if ((len = handlerQueue.push(task)) === 1) {
nextTick(drainQueue);
}
return len;
};
retFunc.clear = function (n) {
if (n <= handlerQueue.length) {
handlerQueue[n - 1] = function () {};
}
return this;
};
module.exports = retFunc;
});
require.register("calvinmetcalf-setImmediate/lib/nextTick.js", function(exports, require, module){
"use strict";
exports.test = function () {
// Don't get fooled by e.g. browserify environments.
return typeof process === "object" && Object.prototype.toString.call(process) === "[object process]";
};
exports.install = function () {
return process.nextTick;
};
});
require.register("calvinmetcalf-setImmediate/lib/postMessage.js", function(exports, require, module){
"use strict";
var globe = require("./global");
exports.test = function () {
// The test against `importScripts` prevents this implementation from being installed inside a web worker,
// where `global.postMessage` means something completely different and can"t be used for this purpose.
if (!globe.postMessage || globe.importScripts) {
return false;
}
var postMessageIsAsynchronous = true;
var oldOnMessage = globe.onmessage;
globe.onmessage = function () {
postMessageIsAsynchronous = false;
};
globe.postMessage("", "*");
globe.onmessage = oldOnMessage;
return postMessageIsAsynchronous;
};
exports.install = function (func) {
var codeWord = "com.calvinmetcalf.setImmediate" + Math.random();
function globalMessage(event) {
if (event.source === globe && event.data === codeWord) {
func();
}
}
if (globe.addEventListener) {
globe.addEventListener("message", globalMessage, false);
} else {
globe.attachEvent("onmessage", globalMessage);
}
return function () {
globe.postMessage(codeWord, "*");
};
};
});
require.register("calvinmetcalf-setImmediate/lib/messageChannel.js", function(exports, require, module){
"use strict";
var globe = require("./global");
exports.test = function () {
return !!globe.MessageChannel;
};
exports.install = function (func) {
var channel = new globe.MessageChannel();
channel.port1.onmessage = func;
return function () {
channel.port2.postMessage(0);
};
};
});
require.register("calvinmetcalf-setImmediate/lib/stateChange.js", function(exports, require, module){
"use strict";
var globe = require("./global");
exports.test = function () {
return "document" in globe && "onreadystatechange" in globe.document.createElement("script");
};
exports.install = function (handle) {
return function () {
// Create a <script> element; its readystatechange event will be fired asynchronously once it is inserted
// into the document. Do so, thus queuing up the task. Remember to clean up once it's been called.
var scriptEl = globe.document.createElement("script");
scriptEl.onreadystatechange = function () {
handle();
scriptEl.onreadystatechange = null;
scriptEl.parentNode.removeChild(scriptEl);
scriptEl = null;
};
globe.document.documentElement.appendChild(scriptEl);
return handle;
};
};
});
require.register("calvinmetcalf-setImmediate/lib/timeout.js", function(exports, require, module){
"use strict";
exports.test = function () {
return true;
};
exports.install = function (t) {
return function () {
setTimeout(t, 0);
};
};
});
require.register("calvinmetcalf-setImmediate/lib/global.js", function(exports, require, module){
module.exports = typeof global === "object" && global ? global : this;
});
require.register("calvinmetcalf-setImmediate/lib/mutation.js", function(exports, require, module){
"use strict";
//based off rsvp
//https://github.com/tildeio/rsvp.js/blob/master/lib/rsvp/async.js
var globe = require("./global");
var MutationObserver = globe.MutationObserver || globe.WebKitMutationObserver;
exports.test = function () {
return MutationObserver;
};
exports.install = function (handle) {
var observer = new MutationObserver(handle);
var element = globe.document.createElement("div");
observer.observe(element, { attributes: true });
// Chrome Memory Leak: https://bugs.webkit.org/show_bug.cgi?id=93661
globe.addEventListener("unload", function () {
observer.disconnect();
observer = null;
}, false);
return function () {
element.setAttribute("drainQueue", "drainQueue");
};
};
});
require.register("lie/lie.js", function(exports, require, module){
var immediate = require('immediate');
// Creates a deferred: an object with a promise and corresponding resolve/reject methods
function Promise(resolver) {
if (!(this instanceof Promise)) {
return new Promise(resolver);
}
var queue = [];
var resolved = false;
// The `handler` variable points to the function that will
// 1) handle a .then(onFulfilled, onRejected) call
// 2) handle a .resolve or .reject call (if not fulfilled)
// Before 2), `handler` holds a queue of callbacks.
// After 2), `handler` is a simple .then handler.
// We use only one function to save memory and complexity.
// Case 1) handle a .then(onFulfilled, onRejected) call
function pending(onFulfilled, onRejected){
return Promise(function(resolver,rejecter){
queue.push({
resolve: onFulfilled,
reject: onRejected,
resolver:resolver,
rejecter:rejecter
});
});
}
function then(onFulfilled, onRejected) {
return resolved?resolved(onFulfilled, onRejected):pending(onFulfilled, onRejected);
}
// Case 2) handle a .resolve or .reject call
// (`onFulfilled` acts as a sentinel)
// The actual function signature is
// .re[ject|solve](sentinel, success, value)
function resolve(success, value){
var action = success ? 'resolve' : 'reject';
var queued;
var callback;
for (var i = 0, l = queue.length; i < l; i++) {
queued = queue[i];
callback = queued[action];
if (typeof callback === 'function') {
immediate(execute,callback, value, queued.resolver, queued.rejecter);
}else if(success){
queued.resolver(value);
}else{
queued.rejecter(value);
}
}
// Replace this handler with a simple resolved or rejected handler
resolved = createHandler(then, value, success);
}
this.then = then;
function yes(value) {
if (!resolved) {
resolve(true, value);
}
}
function no (reason) {
if (!resolved) {
resolve(false, reason);
}
}
try{
resolver(function(a){
if(a && typeof a.then==='function'){
a.then(yes,no);
}else{
yes(a);
}
},no);
}catch(e){
no(e);
}
}
// Creates a fulfilled or rejected .then function
function createHandler(then, value, success) {
return function(onFulfilled, onRejected) {
var callback = success ? onFulfilled : onRejected;
if (typeof callback !== 'function') {
return Promise(function(resolve,reject){
then(resolve,reject);
});
}
return Promise(function(resolve,reject){
immediate(execute,callback,value,resolve,reject);
});
};
}
// Executes the callback with the specified value,
// resolving or rejecting the deferred
function execute(callback, value, resolve, reject) {
try {
var result = callback(value);
if (result && typeof result.then === 'function') {
result.then(resolve, reject);
}
else {
resolve(result);
}
}
catch (error) {
reject(error);
}
}
module.exports = Promise;
});
require.alias("calvinmetcalf-setImmediate/lib/index.js", "lie/deps/immediate/lib/index.js");
require.alias("calvinmetcalf-setImmediate/lib/nextTick.js", "lie/deps/immediate/lib/nextTick.js");
require.alias("calvinmetcalf-setImmediate/lib/postMessage.js", "lie/deps/immediate/lib/postMessage.js");
require.alias("calvinmetcalf-setImmediate/lib/messageChannel.js", "lie/deps/immediate/lib/messageChannel.js");
require.alias("calvinmetcalf-setImmediate/lib/stateChange.js", "lie/deps/immediate/lib/stateChange.js");
require.alias("calvinmetcalf-setImmediate/lib/timeout.js", "lie/deps/immediate/lib/timeout.js");
require.alias("calvinmetcalf-setImmediate/lib/global.js", "lie/deps/immediate/lib/global.js");
require.alias("calvinmetcalf-setImmediate/lib/mutation.js", "lie/deps/immediate/lib/mutation.js");
require.alias("calvinmetcalf-setImmediate/lib/index.js", "lie/deps/immediate/index.js");
require.alias("calvinmetcalf-setImmediate/lib/index.js", "immediate/index.js");
require.alias("calvinmetcalf-setImmediate/lib/index.js", "calvinmetcalf-setImmediate/index.js");
require.alias("lie/lie.js", "lie/index.js");
L.Util.Promise = require("lie");
})();
L.Util.ajax = function(url, options) {
'use strict';
options = options || {};
if (options.jsonp) {
return L.Util.ajax.jsonp(url, options);
}
var request;
var cancel;
var out = L.Util.Promise(function(resolve,reject){
var Ajax;
cancel=reject;
// the following is from JavaScript: The Definitive Guide
if (window.XMLHttpRequest === undefined) {
Ajax = function() {
try {
return new ActiveXObject('Microsoft.XMLHTTP.6.0');
}
catch (e1) {
try {
return new ActiveXObject('Microsoft.XMLHTTP.3.0');
}
catch (e2) {
reject('XMLHttpRequest is not supported');
}
}
};
}
else {
Ajax = window.XMLHttpRequest;
}
var response;
request = new Ajax();
request.open('GET', url);
request.onreadystatechange = function() {
/*jslint evil: true */
if (request.readyState === 4) {
if((request.status < 400&&options.local)|| request.status===200) {
if (window.JSON) {
response = JSON.parse(request.responseText);
} else if (options.evil) {
response = eval('(' + request.responseText + ')');
}
resolve(response);
} else {
if(!request.status){
reject('Attempted cross origin request without CORS enabled');
}else{
reject(request.statusText);
}
}
}
};
request.send();
});
out.then(null,function(reason){
request.abort();
return reason;
});
out.abort = cancel;
return out;
};
L.Util.jsonp = function(url, options) {
options = options || {};
var head = document.getElementsByTagName('head')[0];
var scriptNode = L.DomUtil.create('script', '', head);
var cbName, ourl, cbSuffix, cancel;
var out = L.Util.Promise(function(resolve, reject){
cancel=reject;
var cbParam = options.cbParam || 'callback';
if (options.callbackName) {
cbName = options.callbackName;
}
else {
cbSuffix = '_' + ('' + Math.random()).slice(2);
cbName = 'L.Util.jsonp.cb.' + cbSuffix;
}
scriptNode.type = 'text/javascript';
if (cbSuffix) {
L.Util.jsonp.cb[cbSuffix] = function(data) {
head.removeChild(scriptNode);
delete L.Util.jsonp.cb[cbSuffix];
resolve(data);
};
}
if (url.indexOf('?') === -1) {
ourl = url + '?' + cbParam + '=' + cbName;
}
else {
ourl = url + '&' + cbParam + '=' + cbName;
}
scriptNode.src = ourl;
}).then(null,function(reason){
head.removeChild(scriptNode);
delete L.Util.ajax.cb[cbSuffix];
return reason;
});
out.abort = cancel;
return out;
};
L.Util.jsonp.cb = {};
L.GeoJSON.AJAX = L.GeoJSON.extend({
defaultAJAXparams: {
dataType: 'json',
callbackParam: 'callback',
local:false,
middleware: function(f) {
return f;
}
},
initialize: function(url, options) {
this.urls = [];
if (url) {
if (typeof url === 'string') {
this.urls.push(url);
}
else if (typeof url.pop === 'function') {
this.urls = this.urls.concat(url);
}
else {
options = url;
url = undefined;
}
}
var ajaxParams = L.Util.extend({}, this.defaultAJAXparams);
for (var i in options) {
if (this.defaultAJAXparams.hasOwnProperty(i)) {
ajaxParams[i] = options[i];
}
}
this.ajaxParams = ajaxParams;
this._layers = {};
L.Util.setOptions(this, options);
this.on('data:loaded', function() {
if (this.filter) {
this.refilter(this.filter);
}
}, this);
var self = this;
if (this.urls.length > 0) {
L.Util.Promise(function(yes){
yes();
}).then(function(){
self.addUrl();
});
}
},
clearLayers: function() {
this.urls = [];
L.GeoJSON.prototype.clearLayers.call(this);
return this;
},
addUrl: function(url) {
var self = this;
if (url) {
if (typeof url === 'string') {
self.urls.push(url);
}
else if (typeof url.pop === 'function') {
self.urls = self.urls.concat(url);
}
}
var loading = self.urls.length;
var done = 0;
self.fire('data:loading');
self.urls.forEach(function(url) {
if (self.ajaxParams.dataType.toLowerCase() === 'json') {
L.Util.ajax(url,self.ajaxParams).then(function(d) {
var data = self.ajaxParams.middleware(d);
self.addData(data);
self.fire('data:progress',data);
},function(err){
self.fire('data:progress',{error:err});
});
}
else if (self.ajaxParams.dataType.toLowerCase() === 'jsonp') {
L.Util.jsonp(url,self.ajaxParams).then(function(d) {
var data = self.ajaxParams.middleware(d);
self.addData(data);
self.fire('data:progress',data);
},function(err){
self.fire('data:progress',{error:err});
});
}
});
self.on('data:progress', function() {
if (++done === loading) {
self.fire('data:loaded');
}
});
},
refresh: function(url) {
url = url || this.urls;
this.clearLayers();
this.addUrl(url);
},
refilter: function(func) {
if (typeof func !== 'function') {
this.filter = false;
this.eachLayer(function(a) {
a.setStyle({
stroke: true,
clickable: true
});
});
}
else {
this.filter = func;
this.eachLayer(function(a) {
if (func(a.feature)) {
a.setStyle({
stroke: true,
clickable: true
});
}
else {
a.setStyle({
stroke: false,
clickable: false
});
}
});
}
}
});
L.geoJson.ajax = function(geojson, options) {
return new L.GeoJSON.AJAX(geojson, options);
};

View File

@ -1,125 +0,0 @@
/*
Leaflet.AwesomeMarkers, a plugin that adds colorful iconic markers for Leaflet, based on the Font Awesome icons
(c) 2012-2013, Lennard Voogdt
http://leafletjs.com
https://github.com/lvoogdt
*/
/*global L*/
(function (window, document, undefined) {
"use strict";
/*
* Leaflet.AwesomeMarkers assumes that you have already included the Leaflet library.
*/
L.AwesomeMarkers = {};
L.AwesomeMarkers.version = '2.0.1';
L.AwesomeMarkers.Icon = L.Icon.extend({
options: {
iconSize: [35, 45],
iconAnchor: [17, 42],
popupAnchor: [1, -32],
shadowAnchor: [10, 12],
shadowSize: [36, 16],
className: 'awesome-marker',
prefix: 'glyphicon',
spinClass: 'fa-spin',
extraClasses: '',
icon: 'home',
markerColor: 'blue',
iconColor: 'white'
},
initialize: function (options) {
options = L.Util.setOptions(this, options);
},
createIcon: function () {
var div = document.createElement('div'),
options = this.options;
if (options.icon) {
div.innerHTML = this._createInner();
}
if (options.bgPos) {
div.style.backgroundPosition =
(-options.bgPos.x) + 'px ' + (-options.bgPos.y) + 'px';
}
this._setIconStyles(div, 'icon-' + options.markerColor);
return div;
},
_createInner: function() {
var iconClass, iconSpinClass = "", iconColorClass = "", iconColorStyle = "", options = this.options;
if(options.icon.slice(0,options.prefix.length+1) === options.prefix + "-") {
iconClass = options.icon;
} else {
iconClass = options.prefix + "-" + options.icon;
}
if(options.spin && typeof options.spinClass === "string") {
iconSpinClass = options.spinClass;
}
if(options.iconColor) {
if(options.iconColor === 'white' || options.iconColor === 'black') {
iconColorClass = "icon-" + options.iconColor;
} else {
iconColorStyle = "style='color: " + options.iconColor + "' ";
}
}
return "<i " + iconColorStyle + "class='" + options.extraClasses + " " + options.prefix + " " + iconClass + " " + iconSpinClass + " " + iconColorClass + "'></i>";
},
_setIconStyles: function (img, name) {
var options = this.options,
size = L.point(options[name === 'shadow' ? 'shadowSize' : 'iconSize']),
anchor;
if (name === 'shadow') {
anchor = L.point(options.shadowAnchor || options.iconAnchor);
} else {
anchor = L.point(options.iconAnchor);
}
if (!anchor && size) {
anchor = size.divideBy(2, true);
}
img.className = 'awesome-marker-' + name + ' ' + options.className;
if (anchor) {
img.style.marginLeft = (-anchor.x) + 'px';
img.style.marginTop = (-anchor.y) + 'px';
}
if (size) {
img.style.width = size.x + 'px';
img.style.height = size.y + 'px';
}
},
createShadow: function () {
var div = document.createElement('div');
this._setIconStyles(div, 'shadow');
return div;
}
});
L.AwesomeMarkers.icon = function (options) {
return new L.AwesomeMarkers.Icon(options);
};
}(this, document));

File diff suppressed because one or more lines are too long

Binary file not shown.

Before

Width:  |  Height:  |  Size: 157 B