Custom-Tools zur Kartengestaltung
Dieser Trick-Artikel ist als ein Sammelbecken für Custom-Tools gedacht. Es muss ja nicht jeder das Rad neu erfinden. Wenn ihr was Tolles habt: bitte gerne teilen.
(In Geolocation 2.0 wurde der Namespace von Geolocation
in FriendsOfRedaxo\Geolocation
geändert!)
Lies mich
Geolocation liefert nur wenige fest installierte JS-Tools mit aus, über die Karten-Elemente via Leaflet eingeblendet werden können
position
: einen einfachen roten Marker.marker
: eine Liste einfacher, blauer Marker.bounds
: rechteckiger Bereich, der die initial angezeigte Karte über Kordinaten definiert.geojson
: ein rudimentäres geoJson-Tool
Aber: das System kann einfach erweitert werden, um die vielen verschiedenen individuellen Anforderungen passgenau zu bedienen.
Wie, dass ist in der Tool-Dokumentation
beschrieben. Im JS-Source-Code install/geolocation.js
findet man die Default-Tools; in docs/example/geolocation.js
stehen die Beispiele für Custom-Tools aus der Dokumentation, darunter
center
: Kartenmittelpunkt/Zoom-Level; ohne Marker, als klassische Alternative zubounds
.nrmarker
: Eine Markerliste (marker
), aber mit Nummer im Marker.
Einzel-Marker mit Popup-Text
Kurzbeschreibung
Im Grunde handelt es sich um einen Position-Marker (Tool: position
). Die Klasse Geolocation.Tools.Position
wird um
einen Popup-Text erweitert. Es reicht aus, die SetValue-Methode zu überschreiben. Wurde der Position-Marker erfolgreich
angelegt (gültige Koordinaten), hängt die Methode den Popup-Text an den Marker.
PHP-Datensatz
$dataset = [
[breitengrad,längengrad], // übliche Koordinatenangabe
popup_text, // optionaler Text; ohne Text ein normaler Marker ohne Popup
marker_farbe // optional die Markerfarbe; Default: Geolocation.default.positionColor
];
Der JS-Code für das Tool
Geolocation.Tools.PositionPlus = class extends Geolocation.Tools.Position{
setValue( dataset ) {
// keine Koordinaten => Abbruch
if( !dataset[0] ) return this;
// GGf. Default-Farbe temporär ändern, normalen Position-Marker erzeugen
let color = Geolocation.default.positionColor;
Geolocation.default.positionColor = dataset[2] || Geolocation.default.positionColor;
super.setValue(dataset[0]);
Geolocation.default.positionColor = color;
// Wenn angegeben: Text als Popup hinzufügen
if( this.marker && dataset[1] ) {
this.marker.bindPopup(dataset[1]);
this.marker.on('click', function (e) {
// NOTE: ja, ist so - isPopupOpen liefert true wenn geschlossen.
if( this.isPopupOpen() ) {
this.openPopup();
} else {
this.closePopup();
}
});
}
return this;
}
};
Geolocation.tools.positionplus = function(...args) { return new Geolocation.Tools.PositionPlus(args); };
Beispiel
use FriendsOfRedaxo\Geolocation\Mapset;
use FriendsOfRedaxo\Geolocation\Calc\Box;
use FriendsOfRedaxo\Geolocation\Calc\Point;
$konstanz = Point::byLatLng([47.658968, 9.178456]);
$bounds = Box::byInnerCircle($konstanz,5000);
$position = [
$konstanz->latLng(),
'<strong>Konstanz:</strong> '.$konstanz->text(Point::DMS),
];
echo Mapset::take()
->dataset('bounds',$bounds->latLng())
->dataset('positionplus',$position)
->parse();
Kartenanzeige
Markerliste mit Popup-Text
Kurzbeschreibung
Im Grunde handelt es sich um eine Marker-Liste (Tool: marker
). Die Klasse Geolocation.Tools.Marker
wird um Popup-Texte je Marker erweitert. Es reicht aus, die SetValue-Methode zu überschreiben. Wurde ein
Marker erfolgreich angelegt (gültige Koordinaten), hängt die Methode den Popup-Text an den Marker.
PHP-Datensatz
$dataset = [
[
[breitengrad,längengrad], // übliche Koordinatenangabe
popup_text, // optionaler Text; ohne Text ein normaler Marker ohne Popup
marker_farbe // optional die Markerfarbe; Default: Geolocation.default.markerColor
],
...
];
Der JS-Code für das Tool
Geolocation.Tools.MarkerPlus = class extends Geolocation.Tools.Marker{
setValue( markerArray ) {
if( this.map ) {
let map = this.map;
this.remove();
this.map = map;
}
this.marker = [];
markerArray.forEach( (data) => {
let pos = L.latLng( data[0] );
if( !pos ) return;
let marker = L.marker( pos );
if( !marker ) return;
marker.setIcon( Geolocation.svgIconPin( data[2] || Geolocation.default.markerColor ) );
if( data[1] ) {
marker.bindPopup(data[1]);
marker.on('click', function (e) {
// NOTE: ja, ist so - isPopupOpen liefert true wenn geschlossen.
if( this.isPopupOpen() ) {
this.openPopup();
} else {
this.closePopup();
}
});
}
this.marker.push( marker );
} );
if( this.map ) this.show( this.map );
return this;
}
};
Geolocation.tools.markerplus = function(...args) { return new Geolocation.Tools.MarkerPlus(args); };
Beispiel
use FriendsOfRedaxo\Geolocation\Calc\Box;
use FriendsOfRedaxo\Geolocation\Calc\Point;
use FriendsOfRedaxo\Geolocation\Mapset;
$konstanz = Point::byLatLng([47.658968, 9.178456]);
$kressbronn = Point::byLatLng([47.586204, 9.560653]);
$friedrichshafen = Point::byLatLng([47.651695, 9.485064]);
$bounds = Box::factory([$konstanz, $friedrichshafen, $kressbronn]);
$marker = [
[$konstanz->latLng(), '<strong>Konstanz:</strong> ' . $konstanz->text(Point::DMS), 'DarkSeaGreen'],
[$friedrichshafen->latLng(), '<strong>Friedrichshafen:</strong> ' . $friedrichshafen->text(Point::DMS), 'ForestGreen'],
[$kressbronn->latLng(), '<strong>Konstanz:</strong> ' . $kressbronn->text(Point::DMS)],
];
echo Mapset::take()
->dataset('bounds', $bounds->latLng())
->dataset('markerplus', $marker)
->parse();
Kartenanzeige
Nummerierte Markerliste mit Popup-Text
Kurzbeschreibung
Im Grunde handelt es sich um eine nummerierte Marker-Liste (Tool: nrmarker
aus den
(Beispielen).
Die Klasse Geolocation.Tools.Marker
wird um Popup-Texte und die Nummer je Marker erweitert. Es reicht aus,
die SetValue-Methode zu überschreiben. Wurde ein Marker erfolgreich angelegt (gültige Koordinaten), hängt die
Methode den Popup-Text an den Marker. Die Nummer ist ein optionaler Parameter bei Geolocation.svgIconPin(..)
.
PHP-Datensatz
$dataset = [
[
[breitengrad,längengrad], // übliche Koordinatenangabe
popup_text, // optionaler Text; ohne Text ein normaler Marker ohne Popup
marker_nr // optional die Nummer des Markers; Default: ohne
marker_farbe // optional die Markerfarbe; Default: Geolocation.default.markerColor
],
...
];
Der JS-Code für das Tool
Geolocation.Tools.NrMarkerPlus = class extends Geolocation.Tools.Marker{
setValue( markerArray ) {
if( this.map ) {
let map = this.map;
this.remove();
this.map = map;
}
this.marker = [];
markerArray.forEach( (data) => {
let pos = L.latLng( data[0] );
if( !pos ) return;
let marker = L.marker( pos );
if( !marker ) return;
marker.setIcon( Geolocation.svgIconPin( data[3] || Geolocation.default.markerColor, data[2] || '', 'darkred' ) );
if( data[1] ) {
marker.bindPopup(data[1]);
marker.on('click', function (e) {
// NOTE: ja, ist so - isPopupOpen liefert true wenn geschlossen.
if( this.isPopupOpen() ) {
this.openPopup();
} else {
this.closePopup();
}
});
}
this.marker.push( marker );
} );
if( this.map ) this.show( this.map );
return this;
}
};
Geolocation.tools.nrmarkerplus = function(...args) { return new Geolocation.Tools.NrMarkerPlus(args); };
Beispiel
use FriendsOfRedaxo\Geolocation\Calc\Box;
use FriendsOfRedaxo\Geolocation\Calc\Point;
use FriendsOfRedaxo\Geolocation\Mapset;
$konstanz = Point::byLatLng([47.658968, 9.178456]);
$kressbronn = Point::byLatLng([47.586204, 9.560653]);
$friedrichshafen = Point::byLatLng([47.651695, 9.485064]);
$bounds = Box::factory([$konstanz,$friedrichshafen,$kressbronn]);
$marker = [
[$konstanz->latLng(), '<strong>Konstanz:</strong> '.$konstanz->text(Point::DMS), 1, 'DarkSeaGreen'],
[$friedrichshafen->latLng(),'<strong>Friedrichshafen:</strong> '.$friedrichshafen->text(Point::DMS), 2, 'ForestGreen'],
[$kressbronn->latLng(),'<strong>Konstanz:</strong> '.$kressbronn->text(Point::DMS), 3],
];
echo Mapset::take()
->dataset('bounds',$bounds->latLng())
->dataset('nrmarkerplus',$marker)
->parse();
Kartenanzeige
Nummerierte Markerliste mit Popup-Text als Karten-Overlay
Kurzbeschreibung
(benötigt Geolocation ab Version 2.3.0)
Diese Weiterentwicklung des Tools MarkerPlus fasst die Marker in einer Leaflet-LayerGroup zusammen. Die LayerGroup erhält einen Eintrag in der Karten-Auswahl, genauer: Auswahl der Overlay-Karten. Wie das genau funktioniert ist in der LeafLet-Dokumentation beschrieben (Layer Groups and Layers Control).
Das Tool basisiert diesmal auf dem Geolocation.Tools.Template
, da ohnehin alle Methoden überschrieben werden.
In setValue
wird das Dataset-Array ausgewertet, die Marker erzeugt und in der LAyerGroup zusammengefasst. In show
und remove
wird zusätzlich der Eintrag im Overlay-Menü verwaltet.
PHP-Datensatz
$dataset = [
label, // Titel für den Oberlay-Layer im Overlay-Menü
aktiviert, // true oder false; wenn true wird der Layer sofort aufgeblendet
[
[breitengrad,längengrad], // übliche Koordinatenangabe
popup_text, // optionaler Text; ohne Text ein normaler Marker ohne Popup
marker_nr // optional die Nummer des Markers; Default: ohne
marker_farbe // optional die Markerfarbe; Default: Geolocation.default.markerColor
],
...
];
Der JS-Code für das Tool
Geolocation.Tools.MarkerOverlay = class extends Geolocation.Tools.Template{
setValue( overlayArray ) {
if( this.map ) {
let map = this.map;
this.remove();
this.map = map;
}
this.label = overlayArray[0];
this.active = overlayArray[1] === true;
this.markerGroup = L.layerGroup();
overlayArray[2].forEach( (data) => {
let pos = L.latLng( data[0] );
if( !pos ) return;
let marker = L.marker( pos );
if( !marker ) return;
marker.setIcon( Geolocation.svgIconPin( data[2] || Geolocation.default.markerColor ) );
if( data[1] ) {
marker.bindPopup(data[1]);
marker.on('click', function (e) {
// NOTE: ja, ist so - isPopupOpen liefert true wenn geschlossen.
if( this.isPopupOpen() ) {
this.openPopup();
} else {
this.closePopup();
}
});
}
this.markerGroup.addLayer( marker );
} );
if( this.map ) this.show( this.map );
return this;
}
show (map) {
super.show( map );
if( this.markerGroup instanceof L.LayerGroup ) {
if( this.active) {
this.markerGroup.addTo( map );
}
let layerControl = map._container.__rmMap.layerControl;
layerControl.addOverlay( this.markerGroup, this.label );
}
return this;
}
remove(){
if( this.markerGroup instanceof L.LayerGroup ) {
this.markerGroup.removeFrom(this.map);
let layerControl = map._container.__rmMap.layerControl;
layerControl.removeLayer( this.markerGroup );
}
super.remove();
return this;
}
getCurrentBounds(){
let rect = L.latLngBounds();
if( this.markerGroup instanceof L.LayerGroup ) {
this.markerGroup.eachLayer( (marker) => {
rect.extend( marker.getLatLng() );
});
}
return rect;
}
};
Geolocation.tools.markeroverlay = function(...args) { return new Geolocation.Tools.MarkerOverlay(args); };
Beispiel
use FriendsOfRedaxo\Geolocation\Calc\Box;
use FriendsOfRedaxo\Geolocation\Calc\Point;
use FriendsOfRedaxo\Geolocation\Mapset;
$konstanz = Point::byLatLng([47.658968, 9.178456]);
$kressbronn = Point::byLatLng([47.586204, 9.560653]);
$friedrichshafen = Point::byLatLng([47.651695, 9.485064]);
$bounds = Box::factory([$konstanz, $friedrichshafen, $kressbronn]);
$overlay = [
'Häfen',
false,
[
[$konstanz->latLng(), '<strong>Konstanz:</strong> ' . $konstanz->text(Point::DMS), 'Red'],
[$friedrichshafen->latLng(), '<strong>Friedrichshafen:</strong> ' . $friedrichshafen->text(Point::DMS), 'ForestGreen'],
[$kressbronn->latLng(), '<strong>Konstanz:</strong> ' . $kressbronn->text(Point::DMS)],
],
];
echo Mapset::take()
->dataset('bounds', $bounds->latLng())
->dataset('markeroverlay', $overlay)
->parse();