Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Fix problem with marker icon created via map-area.html by using the _…
…detectImagePath method of M.MapMLLayer. There is some magic about the global L variable that the M variable doesn't match, for reasons not understood by me, yet.
- Loading branch information
1 parent
4d1892b
commit c5a3984
Showing
1 changed file
with
169 additions
and
167 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,167 +1,169 @@ | ||
<link rel="import" href="./bower_components/polymer/polymer.html"> | ||
<link rel="import" href="map-styles.html"> | ||
|
||
<script src="./bower_components/polymer-leaflet/leaflet-src.js"></script> | ||
<script src="./bower_components/proj4/dist/proj4.js"></script> | ||
<script src="./bower_components/proj4leaflet/src/proj4leaflet.js"></script> | ||
<script src="./bower_components/mapml-leaflet-plugin/mapml.js"></script> | ||
|
||
<dom-module id="map-area"> | ||
<style include="map-styles"> | ||
:host { | ||
display: none; | ||
} | ||
</style> | ||
<script> | ||
MapArea = Polymer({ | ||
is: "map-area", | ||
extends: "area", | ||
properties: { | ||
alt : { | ||
type: String, | ||
reflectToAttribute: true | ||
}, | ||
coords : { | ||
type: String, | ||
reflectToAttribute: true | ||
}, | ||
href : { | ||
type: String, | ||
reflectToAttribute: true | ||
}, | ||
shape : { | ||
type: String, | ||
/* to HTML5's default, circle, poly and rect, add marker, line */ | ||
value: 'default', | ||
reflectToAttribute: true | ||
}, | ||
rel : { | ||
type: String, | ||
reflectToAttribute: true | ||
}, | ||
type : { | ||
type: String, | ||
reflectToAttribute: true | ||
}, | ||
target : { | ||
type: String, | ||
reflectToAttribute: true | ||
} | ||
}, | ||
attached: function() { | ||
// if the map has been attached, set this layer up wrt Leaflet map | ||
if (this.parentElement._map) { | ||
this._attachedToMap(); | ||
} | ||
}, | ||
_attachedToMap: function() { | ||
// need the map to convert container points to LatLngs | ||
this._map = this.parentElement._map; | ||
var map = this.parentElement._map; | ||
|
||
// don't go through this if already done | ||
if (!this._feature) { | ||
// TODO??? SCALE this.coords if the this._map.poster exists because | ||
// the img might have been scaled by CSS. | ||
// compute the style properties to be applied to the feature | ||
var options = this._styleToPathOptions(window.getComputedStyle(this)), | ||
points = this.coords ? this._coordsToArray(this.coords): null; | ||
// scale points if the poster exists because responsive areas | ||
if (points && this.parentElement.poster) { | ||
var worig = this.parentElement.poster.width, | ||
wresp = this.parentElement.width, | ||
wadjstmnt = (worig - wresp)/2; | ||
for (var i = 0; i< points.length;i++) { | ||
points[i][0] = points[i][0] - wadjstmnt; | ||
} | ||
} | ||
|
||
if (this.shape === 'marker') { | ||
if (this.alt) { | ||
// Leaflet markers use the options.title as a tooltip | ||
options['title'] = this.alt; | ||
} | ||
this._feature = L.marker(map.containerPointToLatLng(points[0]),options).addTo(map); | ||
} else if (this.shape === 'circle') { | ||
var pixelRadius = parseInt(this.coords.split(",")[2]), | ||
pointOnCirc = L.point(points[0]).add(L.point(0,pixelRadius)), | ||
latLngOnCirc = map.containerPointToLatLng(pointOnCirc), | ||
latLngCenter = map.containerPointToLatLng(points[0]), | ||
radiusInMeters = map.distance(latLngCenter, latLngOnCirc); | ||
this._feature = L.circle(latLngCenter, radiusInMeters, options).addTo(map); | ||
} else if (!this.shape || this.shape === 'rect') { | ||
var bounds = L.latLngBounds(map.containerPointToLatLng(points[0]), map.containerPointToLatLng(points[1])); | ||
this._feature = L.rectangle(bounds, options).addTo(map); | ||
} else if (this.shape === 'line') { | ||
this._feature = L.polyline(this._pointsToLatLngs(points),options).addTo(map); | ||
} else if (this.shape === 'poly') { | ||
this._feature = L.polygon(this._pointsToLatLngs(points),options).addTo(map); | ||
} else if (this.shape === 'default') { | ||
// whole initial area of map is a hyperlink | ||
this._feature = L.rectangle(map.getBounds(),options).addTo(map); | ||
} | ||
if (this.shape !== 'marker' && this.alt) { | ||
// other Leaflet features are implemented via SVG. SVG displays tooltips | ||
// based on the <svg:title> graphics child element. | ||
var title = L.SVG.create('title'), | ||
titleText = document.createTextNode(this.alt); | ||
Polymer.dom(title).appendChild(titleText); | ||
Polymer.dom(this._feature._path).appendChild(title); | ||
} | ||
if (this.href) { | ||
// conditionally act on click on an area link. If no link it should be an | ||
// inert area, but Leaflet doesn't quite support this. For a full | ||
// implementation, we could actually use an image map replete with area | ||
// children which would provide the linking / cursor change behaviours | ||
// that are familiar to HTML authors versed in image maps. | ||
this._feature.on('click', function() {if (this.href) {window.open(this.href);}}, this); | ||
} | ||
} | ||
}, | ||
detached: function() { | ||
this._map.removeLayer(this._feature); | ||
delete this._feature; | ||
}, | ||
_coordsToArray: function (containerPoints) { | ||
// returns an array of arrays of coordinate pairs coordsToArray("1,2,3,4") -> [[1,2],[3,4]] | ||
for (var i=1, points = [], coords = containerPoints.split(",");i<coords.length;i+=2) { | ||
points.push([parseInt(coords[i-1]),parseInt(coords[i])]); | ||
} | ||
return points; | ||
}, | ||
_pointsToLatLngs: function(points) { | ||
// points should be an array of nested container coordinates [[x1,y1],[x2,y2](,[xN,yN])] | ||
var latLngArray = []; | ||
if (this._map) { | ||
for (var i=0,map = this._map;i<points.length;i++) { | ||
latLngArray.push(map.containerPointToLatLng(points[i])); | ||
} | ||
} | ||
return latLngArray; | ||
}, | ||
_styleToPathOptions: function(style) { | ||
var options = {}; | ||
if(style.stroke !== 'none') { | ||
options['stroke'] = true; | ||
options['color'] = style.stroke; | ||
options['opacity'] = style.strokeOpacity; | ||
options['weight'] = parseInt(style.strokeWidth); | ||
options['dashArray'] = style.strokeDasharray; | ||
options['lineCap'] = style.strokeLinecap; | ||
options['lineJoin'] = style.strokeLinejoin; | ||
} else { | ||
options['stroke'] = false; | ||
} | ||
if (style.fill !== 'none') { | ||
options['fill'] = true; | ||
options['fillColor'] = style.fill; | ||
options['fillOpacity'] = style.fillOpacity; | ||
options['fillRule'] = style.fillRule; | ||
} else { | ||
options['fill'] = false; | ||
} | ||
return options; | ||
} | ||
}); | ||
</script> | ||
</dom-module> | ||
<link rel="import" href="./bower_components/polymer/polymer.html"> | ||
<link rel="import" href="map-styles.html"> | ||
|
||
<script src="./bower_components/polymer-leaflet/leaflet-src.js"></script> | ||
<script src="./bower_components/proj4/dist/proj4.js"></script> | ||
<script src="./bower_components/proj4leaflet/src/proj4leaflet.js"></script> | ||
<script src="./bower_components/mapml-leaflet-plugin/mapml.js"></script> | ||
|
||
<dom-module id="map-area"> | ||
<style include="map-styles"> | ||
:host { | ||
display: none; | ||
} | ||
</style> | ||
<script> | ||
MapArea = Polymer({ | ||
is: "map-area", | ||
extends: "area", | ||
properties: { | ||
alt : { | ||
type: String, | ||
reflectToAttribute: true | ||
}, | ||
coords : { | ||
type: String, | ||
reflectToAttribute: true | ||
}, | ||
href : { | ||
type: String, | ||
reflectToAttribute: true | ||
}, | ||
shape : { | ||
type: String, | ||
/* to HTML5's default, circle, poly and rect, add marker, line */ | ||
value: 'default', | ||
reflectToAttribute: true | ||
}, | ||
rel : { | ||
type: String, | ||
reflectToAttribute: true | ||
}, | ||
type : { | ||
type: String, | ||
reflectToAttribute: true | ||
}, | ||
target : { | ||
type: String, | ||
reflectToAttribute: true | ||
} | ||
}, | ||
attached: function() { | ||
// if the map has been attached, set this layer up wrt Leaflet map | ||
if (this.parentElement._map) { | ||
this._attachedToMap(); | ||
} | ||
}, | ||
_attachedToMap: function() { | ||
// need the map to convert container points to LatLngs | ||
this._map = this.parentElement._map; | ||
var map = this.parentElement._map; | ||
|
||
// don't go through this if already done | ||
if (!this._feature) { | ||
// TODO??? SCALE this.coords if the this._map.poster exists because | ||
// the img might have been scaled by CSS. | ||
// compute the style properties to be applied to the feature | ||
var options = this._styleToPathOptions(window.getComputedStyle(this)), | ||
points = this.coords ? this._coordsToArray(this.coords): null; | ||
// scale points if the poster exists because responsive areas | ||
if (points && this.parentElement.poster) { | ||
var worig = this.parentElement.poster.width, | ||
wresp = this.parentElement.width, | ||
wadjstmnt = (worig - wresp)/2; | ||
for (var i = 0; i< points.length;i++) { | ||
points[i][0] = points[i][0] - wadjstmnt; | ||
} | ||
} | ||
|
||
if (this.shape === 'marker') { | ||
if (this.alt) { | ||
// Leaflet markers use the options.title as a tooltip | ||
options['title'] = this.alt; | ||
} | ||
// hack | ||
L.Icon.Default.prototype.options.imagePath = M.MapMLLayer.prototype._detectImagePath(map._container); | ||
this._feature = L.marker(map.containerPointToLatLng(points[0]),options).addTo(map); | ||
} else if (this.shape === 'circle') { | ||
var pixelRadius = parseInt(this.coords.split(",")[2]), | ||
pointOnCirc = L.point(points[0]).add(L.point(0,pixelRadius)), | ||
latLngOnCirc = map.containerPointToLatLng(pointOnCirc), | ||
latLngCenter = map.containerPointToLatLng(points[0]), | ||
radiusInMeters = map.distance(latLngCenter, latLngOnCirc); | ||
this._feature = L.circle(latLngCenter, radiusInMeters, options).addTo(map); | ||
} else if (!this.shape || this.shape === 'rect') { | ||
var bounds = L.latLngBounds(map.containerPointToLatLng(points[0]), map.containerPointToLatLng(points[1])); | ||
this._feature = L.rectangle(bounds, options).addTo(map); | ||
} else if (this.shape === 'line') { | ||
this._feature = L.polyline(this._pointsToLatLngs(points),options).addTo(map); | ||
} else if (this.shape === 'poly') { | ||
this._feature = L.polygon(this._pointsToLatLngs(points),options).addTo(map); | ||
} else if (this.shape === 'default') { | ||
// whole initial area of map is a hyperlink | ||
this._feature = L.rectangle(map.getBounds(),options).addTo(map); | ||
} | ||
if (this.shape !== 'marker' && this.alt) { | ||
// other Leaflet features are implemented via SVG. SVG displays tooltips | ||
// based on the <svg:title> graphics child element. | ||
var title = L.SVG.create('title'), | ||
titleText = document.createTextNode(this.alt); | ||
Polymer.dom(title).appendChild(titleText); | ||
Polymer.dom(this._feature._path).appendChild(title); | ||
} | ||
if (this.href) { | ||
// conditionally act on click on an area link. If no link it should be an | ||
// inert area, but Leaflet doesn't quite support this. For a full | ||
// implementation, we could actually use an image map replete with area | ||
// children which would provide the linking / cursor change behaviours | ||
// that are familiar to HTML authors versed in image maps. | ||
this._feature.on('click', function() {if (this.href) {window.open(this.href);}}, this); | ||
} | ||
} | ||
}, | ||
detached: function() { | ||
this._map.removeLayer(this._feature); | ||
delete this._feature; | ||
}, | ||
_coordsToArray: function (containerPoints) { | ||
// returns an array of arrays of coordinate pairs coordsToArray("1,2,3,4") -> [[1,2],[3,4]] | ||
for (var i=1, points = [], coords = containerPoints.split(",");i<coords.length;i+=2) { | ||
points.push([parseInt(coords[i-1]),parseInt(coords[i])]); | ||
} | ||
return points; | ||
}, | ||
_pointsToLatLngs: function(points) { | ||
// points should be an array of nested container coordinates [[x1,y1],[x2,y2](,[xN,yN])] | ||
var latLngArray = []; | ||
if (this._map) { | ||
for (var i=0,map = this._map;i<points.length;i++) { | ||
latLngArray.push(map.containerPointToLatLng(points[i])); | ||
} | ||
} | ||
return latLngArray; | ||
}, | ||
_styleToPathOptions: function(style) { | ||
var options = {}; | ||
if(style.stroke !== 'none') { | ||
options['stroke'] = true; | ||
options['color'] = style.stroke; | ||
options['opacity'] = style.strokeOpacity; | ||
options['weight'] = parseInt(style.strokeWidth); | ||
options['dashArray'] = style.strokeDasharray; | ||
options['lineCap'] = style.strokeLinecap; | ||
options['lineJoin'] = style.strokeLinejoin; | ||
} else { | ||
options['stroke'] = false; | ||
} | ||
if (style.fill !== 'none') { | ||
options['fill'] = true; | ||
options['fillColor'] = style.fill; | ||
options['fillOpacity'] = style.fillOpacity; | ||
options['fillRule'] = style.fillRule; | ||
} else { | ||
options['fill'] = false; | ||
} | ||
return options; | ||
} | ||
}); | ||
</script> | ||
</dom-module> |