mirror of
https://github.com/home-assistant/frontend.git
synced 2025-07-16 05:46:35 +00:00
Make map panel pure JS solution
This commit is contained in:
parent
0b6b308ca3
commit
336e974fe6
@ -14,14 +14,14 @@
|
|||||||
"font-roboto-local": "~1.0.1",
|
"font-roboto-local": "~1.0.1",
|
||||||
"google-apis": "GoogleWebComponents/google-apis#~1.1.6",
|
"google-apis": "GoogleWebComponents/google-apis#~1.1.6",
|
||||||
"iron-elements": "PolymerElements/iron-elements#~1.0.10",
|
"iron-elements": "PolymerElements/iron-elements#~1.0.10",
|
||||||
"leaflet-map": "~1.2.0",
|
|
||||||
"paper-elements": "PolymerElements/paper-elements#~1.0.7",
|
"paper-elements": "PolymerElements/paper-elements#~1.0.7",
|
||||||
"paper-range-slider": "IftachSadeh/paper-range-slider#~0.2.3",
|
"paper-range-slider": "IftachSadeh/paper-range-slider#~0.2.3",
|
||||||
"paper-scroll-header-panel": "~1.0.16",
|
"paper-scroll-header-panel": "~1.0.16",
|
||||||
"pikaday": "~1.4.0",
|
"pikaday": "~1.4.0",
|
||||||
"polymer": "Polymer/polymer#~1.7.0",
|
"polymer": "Polymer/polymer#~1.7.0",
|
||||||
"vaadin-combo-box": "vaadin/vaadin-combo-box#~1.1.5",
|
"vaadin-combo-box": "vaadin/vaadin-combo-box#~1.1.5",
|
||||||
"paper-slider": "1.0.11"
|
"paper-slider": "1.0.11",
|
||||||
|
"leaflet": "^1.0.2"
|
||||||
},
|
},
|
||||||
"resolutions": {
|
"resolutions": {
|
||||||
"paper-slider": "1.0.11"
|
"paper-slider": "1.0.11"
|
||||||
|
@ -4,9 +4,7 @@
|
|||||||
|
|
||||||
<link rel="import" href="../../bower_components/app-layout/app-toolbar/app-toolbar.html">
|
<link rel="import" href="../../bower_components/app-layout/app-toolbar/app-toolbar.html">
|
||||||
|
|
||||||
<link rel="import" href="../../bower_components/leaflet-map/leaflet-map.html">
|
<script src="../../bower_components/leaflet/dist/leaflet.js"></script>
|
||||||
|
|
||||||
<!-- temp work around -->
|
|
||||||
<link rel="stylesheet" href="../../bower_components/leaflet/dist/leaflet.css" />
|
<link rel="stylesheet" href="../../bower_components/leaflet/dist/leaflet.css" />
|
||||||
|
|
||||||
<link rel="import" href="../../src/components/ha-menu-button.html">
|
<link rel="import" href="../../src/components/ha-menu-button.html">
|
||||||
@ -14,19 +12,13 @@
|
|||||||
|
|
||||||
<link rel="import" href="./ha-entity-marker.html">
|
<link rel="import" href="./ha-entity-marker.html">
|
||||||
|
|
||||||
<style>
|
|
||||||
/* Otherwise they go through overlays. */
|
|
||||||
.leaflet-top, .leaflet-bottom {
|
|
||||||
z-index: 0;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
|
|
||||||
<dom-module id="ha-panel-map">
|
<dom-module id="ha-panel-map">
|
||||||
<template>
|
<template>
|
||||||
<style include="ha-style">
|
<style include="ha-style">
|
||||||
leaflet-map {
|
#map {
|
||||||
height: calc(100% - 64px);
|
height: calc(100% - 64px);
|
||||||
width: 100%;
|
width: 100%;
|
||||||
|
z-index: 0;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
||||||
@ -35,48 +27,7 @@
|
|||||||
<div main-title>Map</div>
|
<div main-title>Map</div>
|
||||||
</app-toolbar>
|
</app-toolbar>
|
||||||
|
|
||||||
<leaflet-map fit-to-markers id="map" max-zoom="17">
|
<div id='map'></div>
|
||||||
<leaflet-tilelayer max-zoom="18"
|
|
||||||
url="https://cartodb-basemaps-{s}.global.ssl.fastly.net/light_all/{z}/{x}/{y}.png">
|
|
||||||
© <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors, © <a href="https://cartodb.com/attributions">CartoDB</a>
|
|
||||||
</leaflet-tilelayer>
|
|
||||||
|
|
||||||
<template is='dom-repeat' items='[[zoneEntities]]'>
|
|
||||||
<leaflet-divicon id="[[item.entityId]]" icon-width="24" icon-height="24">
|
|
||||||
<template is='dom-if' if='[[item.attributes.icon]]'>
|
|
||||||
<iron-icon icon$='[[item.attributes.icon]]'></iron-icon>
|
|
||||||
</template>
|
|
||||||
<template is='dom-if' if='[[!item.attributes.icon]]'>[[item.entityDisplay]]</template>
|
|
||||||
</leaflet-divicon>
|
|
||||||
|
|
||||||
<leaflet-marker latitude="[[item.attributes.latitude]]" icon="[[item.entityId]]"
|
|
||||||
longitude="[[item.attributes.longitude]]" title="[[item.entityDisplay]]"
|
|
||||||
no-clickable></leaflet-marker>
|
|
||||||
|
|
||||||
<leaflet-circle latitude="[[item.attributes.latitude]]"
|
|
||||||
longitude="[[item.attributes.longitude]]" no-clickable
|
|
||||||
radius="[[item.attributes.radius]]" fill color="#FF9800">
|
|
||||||
</leaflet-circle>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<template is='dom-repeat' items='[[locationEntities]]'>
|
|
||||||
<leaflet-divicon id="[[item.entityId]]" icon-height="45" icon-width="45">
|
|
||||||
<ha-entity-marker hass='[[hass]]'
|
|
||||||
entity-id="[[item.entityId]]"></ha-entity-marker>
|
|
||||||
</leaflet-divicon>
|
|
||||||
|
|
||||||
<leaflet-marker latitude="[[item.attributes.latitude]]" icon="[[item.entityId]]"
|
|
||||||
longitude="[[item.attributes.longitude]]" title="[[item.entityDisplay]]"
|
|
||||||
></leaflet-marker>
|
|
||||||
|
|
||||||
<template is='dom-if' if='[[item.attributes.gps_accuracy]]'>
|
|
||||||
<leaflet-circle latitude="[[item.attributes.latitude]]"
|
|
||||||
longitude="[[item.attributes.longitude]]" no-clickable
|
|
||||||
radius="[[item.attributes.gps_accuracy]]" fill color="#0288D1">
|
|
||||||
</leaflet-circle>
|
|
||||||
</template>
|
|
||||||
</template>
|
|
||||||
</leaflet-map>
|
|
||||||
</template>
|
</template>
|
||||||
</dom-module>
|
</dom-module>
|
||||||
|
|
||||||
@ -111,31 +62,17 @@ Polymer({
|
|||||||
type: Array,
|
type: Array,
|
||||||
bindNuclear: function (hass) {
|
bindNuclear: function (hass) {
|
||||||
return [
|
return [
|
||||||
hass.entityGetters.visibleEntityMap,
|
hass.entityGetters.entityMap,
|
||||||
function (entities) {
|
function (entities) {
|
||||||
return entities.valueSeq().filter(
|
return entities.valueSeq().filter(
|
||||||
function (entity) {
|
function (entity) {
|
||||||
return entity.attributes.latitude && entity.state !== 'home';
|
return 'latitude' in entity.attributes;
|
||||||
}
|
}
|
||||||
).toArray();
|
);
|
||||||
},
|
|
||||||
];
|
|
||||||
},
|
|
||||||
},
|
|
||||||
|
|
||||||
zoneEntities: {
|
|
||||||
type: Array,
|
|
||||||
bindNuclear: function (hass) {
|
|
||||||
return [
|
|
||||||
hass.entityGetters.entityMap,
|
|
||||||
function (entities) {
|
|
||||||
return entities.valueSeq()
|
|
||||||
.filter(function (entity) {
|
|
||||||
return entity.domain === 'zone' && !entity.attributes.passive;
|
|
||||||
}).toArray();
|
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
},
|
},
|
||||||
|
observer: 'drawEntities',
|
||||||
},
|
},
|
||||||
|
|
||||||
narrow: {
|
narrow: {
|
||||||
@ -149,16 +86,118 @@ Polymer({
|
|||||||
},
|
},
|
||||||
|
|
||||||
attached: function () {
|
attached: function () {
|
||||||
// On Safari, iPhone 5, 5s and some 6 I have observed that the user would be
|
var map = this._map = window.L.map(this.$.map);
|
||||||
// unable to pan on initial load. This fixes it.
|
map.setView([51.505, -0.09], 13);
|
||||||
if (window.L.Browser.mobileWebkit || window.L.Browser.webkit) {
|
window.L.tileLayer(
|
||||||
this.async(function () {
|
'https://cartodb-basemaps-{s}.global.ssl.fastly.net/light_all/{z}/{x}/{y}.png',
|
||||||
var map = this.$.map;
|
{
|
||||||
var prev = map.style.display;
|
attribution: '© <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors, © <a href="https://cartodb.com/attributions">CartoDB</a>',
|
||||||
map.style.display = 'none';
|
maxZoom: 18,
|
||||||
this.async(function () { map.style.display = prev; }, 1);
|
}
|
||||||
}.bind(this), 1);
|
).addTo(map);
|
||||||
|
|
||||||
|
this.drawEntities(this.locationEntities);
|
||||||
|
|
||||||
|
this.async(function () {
|
||||||
|
map.invalidateSize();
|
||||||
|
this.fitMap();
|
||||||
|
}.bind(this), 1);
|
||||||
|
},
|
||||||
|
|
||||||
|
fitMap: function () {
|
||||||
|
var bounds = new window.L.latLngBounds(
|
||||||
|
this._mapItems.map(function (item) { return item.getLatLng(); }));
|
||||||
|
|
||||||
|
this._map.fitBounds(bounds.pad(0.5));
|
||||||
|
},
|
||||||
|
|
||||||
|
drawEntities: function (entities) {
|
||||||
|
/* eslint-disable vars-on-top */
|
||||||
|
var map = this._map;
|
||||||
|
if (!map) return;
|
||||||
|
|
||||||
|
if (this._mapItems) {
|
||||||
|
this._mapItems.forEach(function (marker) { marker.remove(); });
|
||||||
}
|
}
|
||||||
|
var mapItems = this._mapItems = [];
|
||||||
|
|
||||||
|
entities.forEach(function (entity) {
|
||||||
|
var icon;
|
||||||
|
|
||||||
|
if (entity.domain === 'zone') {
|
||||||
|
// DRAW ZONE
|
||||||
|
if (entity.attributes.passive) return;
|
||||||
|
|
||||||
|
// create icon
|
||||||
|
var iconHTML = '';
|
||||||
|
if (entity.attributes.icon) {
|
||||||
|
iconHTML = (
|
||||||
|
"<iron-icon icon='" + entity.attributes.icon + "'></iron-icon>");
|
||||||
|
} else {
|
||||||
|
iconHTML = entity.entityDisplay;
|
||||||
|
}
|
||||||
|
|
||||||
|
icon = window.L.divIcon({
|
||||||
|
html: iconHTML,
|
||||||
|
iconSize: [24, 24],
|
||||||
|
className: '',
|
||||||
|
});
|
||||||
|
|
||||||
|
// create market with the icon
|
||||||
|
mapItems.push(window.L.marker(
|
||||||
|
[entity.attributes.latitude, entity.attributes.longitude],
|
||||||
|
{
|
||||||
|
icon,
|
||||||
|
interactive: false,
|
||||||
|
title: entity.entityDisplay,
|
||||||
|
}
|
||||||
|
).addTo(map));
|
||||||
|
|
||||||
|
// create circle around it
|
||||||
|
mapItems.push(window.L.circle(
|
||||||
|
[entity.attributes.latitude, entity.attributes.longitude],
|
||||||
|
{
|
||||||
|
interactive: false,
|
||||||
|
color: '#FF9800',
|
||||||
|
radius: entity.attributes.radius,
|
||||||
|
}
|
||||||
|
).addTo(map));
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Filter out entities at home
|
||||||
|
if (entity.state === 'home' || entity.attributes.hidden) return;
|
||||||
|
|
||||||
|
// DRAW ENTITY
|
||||||
|
// create icon
|
||||||
|
icon = window.L.divIcon({
|
||||||
|
html: "<ha-entity-marker entity-id='" + entity.entityId + "'></ha-entity-marker>",
|
||||||
|
iconSize: [45, 45],
|
||||||
|
className: '',
|
||||||
|
});
|
||||||
|
|
||||||
|
// create market with the icon
|
||||||
|
mapItems.push(window.L.marker(
|
||||||
|
[entity.attributes.latitude, entity.attributes.longitude],
|
||||||
|
{
|
||||||
|
icon,
|
||||||
|
title: entity.entityDisplay,
|
||||||
|
}
|
||||||
|
).addTo(map));
|
||||||
|
|
||||||
|
// create circle around if entity has accuracy
|
||||||
|
if (entity.attributes.gps_accuracy) {
|
||||||
|
mapItems.push(window.L.circle(
|
||||||
|
[entity.attributes.latitude, entity.attributes.longitude],
|
||||||
|
{
|
||||||
|
interactive: false,
|
||||||
|
color: '#0288D1',
|
||||||
|
radius: entity.attributes.gps_accuracy,
|
||||||
|
}
|
||||||
|
).addTo(map));
|
||||||
|
}
|
||||||
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
computeMenuButtonClass: function (narrow, showMenu) {
|
computeMenuButtonClass: function (narrow, showMenu) {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user