mirror of
https://github.com/home-assistant/frontend.git
synced 2025-04-24 21:37:21 +00:00

* Convert remaining elements to ES6 classes * Use native DOM methods for tests * Fix Polymer 2 debounce call
197 lines
5.5 KiB
HTML
197 lines
5.5 KiB
HTML
<link rel="import" href="../../bower_components/polymer/polymer-element.html">
|
|
<link rel='import' href='../../bower_components/iron-icon/iron-icon.html'>
|
|
<link rel="import" href="../../bower_components/app-layout/app-toolbar/app-toolbar.html">
|
|
|
|
<script src="../../bower_components/leaflet/dist/leaflet.js"></script>
|
|
|
|
<link rel="import" href="../../src/components/ha-menu-button.html">
|
|
<link rel="import" href="./ha-entity-marker.html">
|
|
|
|
<dom-module id="ha-panel-map">
|
|
<template>
|
|
<style include="ha-style">
|
|
#map {
|
|
height: calc(100% - 64px);
|
|
width: 100%;
|
|
z-index: 0;
|
|
}
|
|
</style>
|
|
|
|
<app-toolbar>
|
|
<ha-menu-button narrow='[[narrow]]' show-menu='[[showMenu]]'></ha-menu-button>
|
|
<div main-title>Map</div>
|
|
</app-toolbar>
|
|
|
|
<div id='map'></div>
|
|
</template>
|
|
</dom-module>
|
|
|
|
<script>
|
|
window.L.Icon.Default.imagePath = '/static/images/leaflet';
|
|
|
|
class HaPanelMap extends Polymer.Element {
|
|
static get is() { return 'ha-panel-map'; }
|
|
|
|
static get properties() {
|
|
return {
|
|
hass: {
|
|
type: Object,
|
|
observer: 'drawEntities',
|
|
},
|
|
|
|
narrow: {
|
|
type: Boolean,
|
|
},
|
|
|
|
showMenu: {
|
|
type: Boolean,
|
|
value: false,
|
|
},
|
|
};
|
|
}
|
|
|
|
connectedCallback() {
|
|
super.connectedCallback();
|
|
var map = this._map = window.L.map(this.$.map);
|
|
var style = document.createElement('link');
|
|
style.setAttribute('href', window.HASS_DEV ?
|
|
'/static/home-assistant-polymer/bower_components/leaflet/dist/leaflet.css' :
|
|
'/static/images/leaflet/leaflet.css');
|
|
style.setAttribute('rel', 'stylesheet');
|
|
this.$.map.parentNode.appendChild(style);
|
|
map.setView([51.505, -0.09], 13);
|
|
window.L.tileLayer(
|
|
'https://cartodb-basemaps-{s}.global.ssl.fastly.net/light_all/{z}/{x}/{y}.png',
|
|
{
|
|
attribution: '© <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors, © <a href="https://cartodb.com/attributions">CartoDB</a>',
|
|
maxZoom: 18,
|
|
}
|
|
).addTo(map);
|
|
|
|
this.drawEntities(this.hass);
|
|
|
|
setTimeout(() => {
|
|
map.invalidateSize();
|
|
this.fitMap();
|
|
}, 1);
|
|
}
|
|
|
|
fitMap() {
|
|
var bounds;
|
|
|
|
if (this._mapItems.length === 0) {
|
|
this._map.setView(
|
|
new window.L.LatLng(this.hass.config.core.latitude, this.hass.config.core.longitude),
|
|
14
|
|
);
|
|
} else {
|
|
bounds = new window.L.latLngBounds(this._mapItems.map(item => item.getLatLng()));
|
|
this._map.fitBounds(bounds.pad(0.5));
|
|
}
|
|
}
|
|
|
|
drawEntities(hass) {
|
|
/* 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 = [];
|
|
|
|
Object.keys(hass.states).forEach(function (entityId) {
|
|
var entity = hass.states[entityId];
|
|
var title = window.hassUtil.computeStateName(entity);
|
|
|
|
if ((entity.attributes.hidden &&
|
|
window.hassUtil.computeDomain(entity) !== 'zone') ||
|
|
entity.state === 'home' ||
|
|
!('latitude' in entity.attributes) ||
|
|
!('longitude' in entity.attributes)) {
|
|
return;
|
|
}
|
|
|
|
var icon;
|
|
|
|
if (window.hassUtil.computeDomain(entity) === '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 = title;
|
|
}
|
|
|
|
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: icon,
|
|
interactive: false,
|
|
title: title,
|
|
}
|
|
).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;
|
|
}
|
|
|
|
// DRAW ENTITY
|
|
// create icon
|
|
var entityPicture = entity.attributes.entity_picture || '';
|
|
var entityName = title.split(' ').map(function (part) { return part.substr(0, 1); }).join('');
|
|
/* Leaflet clones this element before adding it to the map. This messes up
|
|
our Poylmer object and we can't pass data through. Thus we hack like this. */
|
|
icon = window.L.divIcon({
|
|
html: "<ha-entity-marker entity-id='" + entity.entity_id + "' entity-name='" + entityName + "' entity-picture='" + entityPicture + "'></ha-entity-marker>",
|
|
iconSize: [45, 45],
|
|
className: '',
|
|
});
|
|
|
|
// create market with the icon
|
|
mapItems.push(window.L.marker(
|
|
[entity.attributes.latitude, entity.attributes.longitude],
|
|
{
|
|
icon: icon,
|
|
title: window.hassUtil.computeStateName(entity),
|
|
}
|
|
).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));
|
|
}
|
|
});
|
|
}
|
|
}
|
|
|
|
customElements.define(HaPanelMap.is, HaPanelMap);
|
|
</script>
|