Compare commits
No commits in common. "66fca1fc027c3999716d49e1a21df6be454c0cdf" and "f8e48f54ca8d0e0abce1cf14e7097e7fd3fe5020" have entirely different histories.
66fca1fc02
...
f8e48f54ca
13 changed files with 252 additions and 971 deletions
|
|
@ -5,7 +5,7 @@
|
|||
<meta http-equiv="Keywords" content="Lists"/>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
|
||||
<link rel="shortcut icon" type="image/png" href="../../../source/UI/themes/oxlight/png/icon16.png"/>
|
||||
<script type="text/javascript" src="../../../dev/Ox.js"></script>
|
||||
<script type="text/javascript" src="../../../min/Ox.js"></script>
|
||||
<script type="text/javascript" src="js/example.js"></script>
|
||||
<script>window.addEventListener('message', function(e) { e.origin == window.location.origin && eval('(' + e.data + ')'); });</script>
|
||||
</head>
|
||||
|
|
|
|||
|
|
@ -1821,7 +1821,6 @@ Maps
|
|||
top: 4px;
|
||||
width: 136px;
|
||||
text-overflow: ellipsis;
|
||||
line-height: 1;
|
||||
}
|
||||
.OxMap .OxPlaceControl.OxPlaceDeselectButton {
|
||||
right: 4px;
|
||||
|
|
@ -2970,20 +2969,3 @@ Miscellaneous
|
|||
.OxTooltip > div {
|
||||
font-size: 9px;
|
||||
}
|
||||
|
||||
/*
|
||||
================================================================================
|
||||
MapLibre GL cleanups
|
||||
================================================================================
|
||||
*/
|
||||
|
||||
.maplibregl-popup-anchor-bottom .maplibregl-popup-tip {
|
||||
display: none !important;
|
||||
}
|
||||
|
||||
.maplibregl-popup-content {
|
||||
padding: 0px !important;
|
||||
border-radius: 5px;
|
||||
top: 50px;
|
||||
left: -4px;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -99,7 +99,6 @@ Ox.Map = function(options, self) {
|
|||
return place.name || '<span class="OxLight">Unnamed</span>';
|
||||
},
|
||||
maxMarkers: 100,
|
||||
nominatim: 'https://nominatim.openstreetmap.org',
|
||||
places: null,
|
||||
selected: '',
|
||||
showControls: false,
|
||||
|
|
@ -107,7 +106,6 @@ Ox.Map = function(options, self) {
|
|||
showStatusbar: false,
|
||||
showToolbar: false,
|
||||
showZoombar: false,
|
||||
style: 'https://tiles.openfreemap.org/styles/liberty',
|
||||
zoomOnlyWhenFocused: false
|
||||
// fixme: width, height
|
||||
})
|
||||
|
|
@ -145,7 +143,7 @@ Ox.Map = function(options, self) {
|
|||
self.map.fitBounds(mapBounds);
|
||||
} else {
|
||||
self.map.setZoom(self.minZoom);
|
||||
self.map.setCenter(new maplibregl.LngLat(0, 0));
|
||||
self.map.setCenter(new google.maps.LatLng(0, 0));
|
||||
}
|
||||
// fixme: the following is just a guess
|
||||
self.boundsChanged = true;
|
||||
|
|
@ -511,27 +509,23 @@ Ox.Map = function(options, self) {
|
|||
$placeControl.css({opacity: 0}).hide();
|
||||
});
|
||||
|
||||
if (window.maplibregl) {
|
||||
if (window.google) {
|
||||
// timeout needed so that the map is in the DOM
|
||||
setTimeout(initMap);
|
||||
} else if (window.googleCallback) {
|
||||
(function interval() {
|
||||
isLoaded() ? initMap() : setTimeout(interval, 100);
|
||||
}());
|
||||
} else {
|
||||
Ox.getStylesheet([
|
||||
Ox.PATH + 'UI/maplibre-gl/maplibre-gl.css',
|
||||
Ox.PATH + 'UI/maplibre-gl/maplibre-gl-geocoder.css'
|
||||
], () => {})
|
||||
$.getScript([
|
||||
Ox.PATH + 'UI/maplibre-gl/maplibre-gl.js',
|
||||
Ox.PATH + 'UI/maplibre-gl/maplibre-gl-geocoder.min.js',
|
||||
], initMap)
|
||||
}
|
||||
|
||||
function equalBonds(a, b) {
|
||||
return (
|
||||
a._sw.lat == b._sw.lat &&
|
||||
a._sw.lng == b._sw.lng &&
|
||||
a._ne.lat == b._ne.lat &&
|
||||
a._ne.lng == b._ne.lng
|
||||
)
|
||||
window.googleCallback = function() {
|
||||
delete window.googleCallback;
|
||||
initMap();
|
||||
};
|
||||
$.getScript(
|
||||
document.location.protocol
|
||||
+ '//maps.google.com/maps/api/js?callback=googleCallback&sensor=false'
|
||||
+ (Ox.Map.GoogleApiKey ? '&key=' + Ox.Map.GoogleApiKey : '')
|
||||
);
|
||||
}
|
||||
|
||||
function addPlaceToMap(place) {
|
||||
|
|
@ -541,11 +535,11 @@ Ox.Map = function(options, self) {
|
|||
if (!place) {
|
||||
var bounds = self.map.getBounds(),
|
||||
center = self.map.getCenter(),
|
||||
southwest = new maplibregl.LngLatBounds(
|
||||
bounds._sw, center
|
||||
southwest = new google.maps.LatLngBounds(
|
||||
bounds.getSouthWest(), center
|
||||
).getCenter(),
|
||||
northeast = new maplibregl.LngLatBounds(
|
||||
center, bounds._ne
|
||||
northeast = new google.maps.LatLngBounds(
|
||||
center, bounds.getNorthEast()
|
||||
).getCenter(),
|
||||
place = new Ox.MapPlace({
|
||||
alternativeNames: [],
|
||||
|
|
@ -556,14 +550,14 @@ Ox.Map = function(options, self) {
|
|||
map: that,
|
||||
name: '',
|
||||
type: 'feature',
|
||||
south: southwest.lat,
|
||||
west: southwest.lng,
|
||||
north: northeast.lat,
|
||||
east: northeast.lng
|
||||
south: southwest.lat(),
|
||||
west: southwest.lng(),
|
||||
north: northeast.lat(),
|
||||
east: northeast.lng()
|
||||
});
|
||||
}
|
||||
Ox.forEach(self.places, function(p, i) {
|
||||
if (equalBonds(place.bounds, p.bounds)) {
|
||||
if (place.bounds.equals(p.bounds)) {
|
||||
place = p;
|
||||
exists = true;
|
||||
return false; // break
|
||||
|
|
@ -599,12 +593,13 @@ Ox.Map = function(options, self) {
|
|||
// checks if outerBounds _can_ contain innerBounds
|
||||
var outerSpan = outerBounds.toSpan(),
|
||||
innerSpan = innerBounds.toSpan();
|
||||
return outerSpan.lat > innerSpan.lat &&
|
||||
outerSpan.lng > innerSpan.lng;
|
||||
return outerSpan.lat() > innerSpan.lat() &&
|
||||
outerSpan.lng() > innerSpan.lng();
|
||||
}
|
||||
|
||||
function centerChanged() {
|
||||
that.tooltip.remove()
|
||||
var tooltip = $('.OxMapMarkerTooltip');
|
||||
tooltip.length && Ox.$elements[$(tooltip[0]).data('oxid')].hide();
|
||||
self.center = self.map.getCenter();
|
||||
self.centerChanged = true;
|
||||
}
|
||||
|
|
@ -616,7 +611,7 @@ Ox.Map = function(options, self) {
|
|||
function clickMap(event) {
|
||||
var place = getSelectedPlace();
|
||||
if (self.options.clickable/* && !editing()*/) {
|
||||
getPlaceByLatLng(event.lngLat, self.map.getBounds(), function(place) {
|
||||
getPlaceByLatLng(event.latLng, self.map.getBounds(), function(place) {
|
||||
if (place) {
|
||||
addPlaceToMap(place);
|
||||
//selectPlace(place.id);
|
||||
|
|
@ -661,7 +656,7 @@ Ox.Map = function(options, self) {
|
|||
|
||||
function crossesDateline() {
|
||||
var bounds = self.map.getBounds();
|
||||
return bounds._sw.lng > bounds._ne.lng;
|
||||
return bounds.getSouthWest().lng() > bounds.getNorthEast().lng();
|
||||
}
|
||||
|
||||
function editing() {
|
||||
|
|
@ -686,9 +681,9 @@ Ox.Map = function(options, self) {
|
|||
// get initial map bounds
|
||||
self.options.places({}, function(result) {
|
||||
var area = result.data.area;
|
||||
callback(new maplibregl.LngLatBounds(
|
||||
new maplibregl.LngLat(area.west, area.south),
|
||||
new maplibregl.LngLat(area.east, area.north)
|
||||
callback(new google.maps.LatLngBounds(
|
||||
new google.maps.LatLng(area.south, area.west),
|
||||
new google.maps.LatLng(area.north, area.east)
|
||||
));
|
||||
});
|
||||
}
|
||||
|
|
@ -709,22 +704,15 @@ Ox.Map = function(options, self) {
|
|||
callback = point;
|
||||
point = self.map.getCenter();
|
||||
}
|
||||
let maxZoom = self.map.getMaxZoom()
|
||||
setTimeout(() => {
|
||||
callback(maxZoom)
|
||||
})
|
||||
/*
|
||||
self.maxZoomService.getMaxZoomAtLatLng(point, function(data) {
|
||||
callback(data.status == 'OK' ? data.zoom : null);
|
||||
});
|
||||
*/
|
||||
}
|
||||
|
||||
function getMetersPerPixel() {
|
||||
// m/px = m/deg * deg/px
|
||||
const degreesPerPixel = 360 / (self.tileSize * Math.pow(2, self.map.getZoom()));
|
||||
const center = self.map.getCenter();
|
||||
return Ox.getMetersPerDegree(center.lat) * degreesPerPixel;
|
||||
var degreesPerPixel = 360 / (self.tileSize * Math.pow(2, self.map.getZoom()));
|
||||
return Ox.getMetersPerDegree(self.map.getCenter().lat()) * degreesPerPixel;
|
||||
}
|
||||
|
||||
function getMinZoom() {
|
||||
|
|
@ -746,16 +734,18 @@ Ox.Map = function(options, self) {
|
|||
: Ox.getObjectById(self.places, id);
|
||||
}
|
||||
|
||||
async function getPlaceByLatLng(latlng, bounds, callback) {
|
||||
function getPlaceByLatLng(latlng, bounds, callback) {
|
||||
// gets the largest place at latlng that would fit in bounds
|
||||
var callback = arguments.length == 3 ? callback : bounds,
|
||||
bounds = arguments.length == 3 ? bounds : null;
|
||||
self.$loadingIcon && self.$loadingIcon.start();
|
||||
var results = await reverseGeocode(latlng);
|
||||
self.geocoder.geocode({
|
||||
latLng: latlng
|
||||
}, function(results, status) {
|
||||
self.$loadingIcon && self.$loadingIcon.stop();
|
||||
if (true) {
|
||||
if (status == google.maps.GeocoderStatus.OK) {
|
||||
if (bounds) {
|
||||
Ox.forEach(results, function(result, i) {
|
||||
Ox.forEach(results.reverse(), function(result, i) {
|
||||
if (
|
||||
i == results.length - 1 ||
|
||||
canContain(bounds, result.geometry.bounds || result.geometry.viewport)
|
||||
|
|
@ -768,7 +758,10 @@ Ox.Map = function(options, self) {
|
|||
callback(new Ox.MapPlace(parseGeodata(results[0])));
|
||||
}
|
||||
}
|
||||
if (!results.length) {
|
||||
if (
|
||||
status == google.maps.GeocoderStatus.OK ||
|
||||
status == google.maps.GeocoderStatus.ZERO_RESULTS
|
||||
) {
|
||||
triggerGeocodeEvent({
|
||||
latLng: latlng,
|
||||
results: results
|
||||
|
|
@ -777,19 +770,25 @@ Ox.Map = function(options, self) {
|
|||
Ox.Log('Map', 'geocode failed:', status);
|
||||
callback(null);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function getPlaceByName(name, callback) {
|
||||
self.$loadingIcon && self.$loadingIcon.start();
|
||||
forwardGeocode({
|
||||
query: name
|
||||
}).then(function(results) {
|
||||
self.geocoder.geocode({
|
||||
address: name
|
||||
}, function(results, status) {
|
||||
self.$loadingIcon && self.$loadingIcon.stop();
|
||||
if (results.features.length) {
|
||||
callback(new Ox.MapPlace(parseGeodata(results.features[0])));
|
||||
if (status == google.maps.GeocoderStatus.OK) {
|
||||
callback(new Ox.MapPlace(parseGeodata(results[0])));
|
||||
}
|
||||
if (
|
||||
status == google.maps.GeocoderStatus.OK
|
||||
&& status != google.maps.GeocoderStatus.ZERO_RESULTS
|
||||
) {
|
||||
triggerGeocodeEvent({
|
||||
address: name,
|
||||
results: results.features
|
||||
results: results
|
||||
});
|
||||
} else {
|
||||
Ox.Log('Map', 'geocode failed:', status);
|
||||
|
|
@ -832,167 +831,36 @@ Ox.Map = function(options, self) {
|
|||
: null;
|
||||
}
|
||||
|
||||
function bbox2bounds(bbox) {
|
||||
return new maplibregl.LngLatBounds(
|
||||
new maplibregl.LngLat(bbox[0], bbox[1]),
|
||||
new maplibregl.LngLat(bbox[2], bbox[3])
|
||||
)
|
||||
}
|
||||
|
||||
function converNominatimFeature(feature) {
|
||||
const center = [
|
||||
feature.bbox[0] +
|
||||
(feature.bbox[2] - feature.bbox[0]) / 2,
|
||||
feature.bbox[1] +
|
||||
(feature.bbox[3] - feature.bbox[1]) / 2
|
||||
];
|
||||
const polygon = {
|
||||
type: 'Feature',
|
||||
geometry: {
|
||||
type: 'Polygon',
|
||||
coordinates: [
|
||||
[feature.bbox[0], feature.bbox[1]],
|
||||
[feature.bbox[1], feature.bbox[2]],
|
||||
[feature.bbox[2], feature.bbox[3]],
|
||||
[feature.bbox[0], feature.bbox[3]],
|
||||
]
|
||||
},
|
||||
bounds: bbox2bounds(feature.bbox),
|
||||
place_name: feature.properties.display_name,
|
||||
properties: feature.properties,
|
||||
text: feature.properties.display_name,
|
||||
address_components: [
|
||||
{
|
||||
long_name: feature.properties.display_name,
|
||||
short_name: feature.properties.display_name,
|
||||
types: ['place']
|
||||
}
|
||||
],
|
||||
place_type: ['place'],
|
||||
};
|
||||
return polygon
|
||||
}
|
||||
|
||||
async function reverseGeocode(config) {
|
||||
const features = [];
|
||||
try {
|
||||
const request = `${self.options.nominatim}/reverse?lat=${
|
||||
config.lat
|
||||
}&lon=${
|
||||
config.lng
|
||||
}&format=geojson&polygon_geojson=1&addressdetails=1`;
|
||||
const response = await fetch(request);
|
||||
const geojson = await response.json();
|
||||
for (const feature of geojson.features) {
|
||||
features.push(converNominatimFeature(feature));
|
||||
}
|
||||
} catch (e) {
|
||||
console.error(`Failed to reverseGeocode with error: ${e}`);
|
||||
}
|
||||
return {
|
||||
features
|
||||
};
|
||||
}
|
||||
async function forwardGeocode(config) {
|
||||
const features = [];
|
||||
try {
|
||||
const request = `${self.options.nominatim}/search?q=${
|
||||
config.query
|
||||
}&format=geojson&polygon_geojson=1&addressdetails=1`;
|
||||
const response = await fetch(request);
|
||||
const geojson = await response.json();
|
||||
for (const feature of geojson.features) {
|
||||
features.push(converNominatimFeature(feature));
|
||||
}
|
||||
} catch (e) {
|
||||
console.error(`Failed to forwardGeocode with error: ${e}`);
|
||||
}
|
||||
|
||||
return {
|
||||
features
|
||||
};
|
||||
}
|
||||
|
||||
function initMap() {
|
||||
|
||||
getMapBounds(function(mapBounds) {
|
||||
|
||||
//Ox.Log('Map', 'init', mapBounds._sw, mapBounds._ne, mapBounds.getCenter())
|
||||
//Ox.Log('Map', 'init', mapBounds.getSouthWest(), mapBounds.getNorthEast(), mapBounds.getCenter())
|
||||
|
||||
//self.elevationService = new google.maps.ElevationService();
|
||||
//self.maxZoomService = new google.maps.MaxZoomService();
|
||||
//
|
||||
self.elevationService = new google.maps.ElevationService();
|
||||
self.geocoder = new google.maps.Geocoder();
|
||||
self.maxZoomService = new google.maps.MaxZoomService();
|
||||
|
||||
self.center = mapBounds ? mapBounds.getCenter() : new maplibregl.LngLat(0, 0);
|
||||
self.center = mapBounds ? mapBounds.getCenter() : new google.maps.LatLng(0, 0);
|
||||
self.zoom = self.minZoom;
|
||||
window.map = that.map = self.map = new maplibregl.Map({
|
||||
container: self.$map[0],
|
||||
that.map = self.map = new google.maps.Map(self.$map[0], {
|
||||
center: self.center,
|
||||
style2: self.options.style,
|
||||
style: {
|
||||
'version': 8,
|
||||
'sources': {
|
||||
'raster-tiles': {
|
||||
'type': 'raster',
|
||||
'tiles': [
|
||||
// FIXME: use protocol and make use of all subdomains
|
||||
//'https://{s}.google.com/vt/lyrs=s&x={x}&y={y}&z={z}'
|
||||
'https://mt0.google.com/vt/lyrs=s&x={x}&y={y}&z={z}'
|
||||
|
||||
],
|
||||
'subdomains':['mt0','mt1','mt2','mt3'],
|
||||
'tileSize': 256,
|
||||
'attribution':
|
||||
'FIXME',
|
||||
}
|
||||
},
|
||||
'layers': [
|
||||
{
|
||||
'id': 'simple-tiles',
|
||||
'type': 'raster',
|
||||
'source': 'raster-tiles',
|
||||
'minzoom': 0,
|
||||
'maxzoom': 22
|
||||
}
|
||||
]
|
||||
},
|
||||
//mapTypeId: google.maps.MapTypeId[getMapType()],
|
||||
//noClear: true,
|
||||
//scrollwheel: !self.options.zoomOnlyWhenFocused,
|
||||
disableDefaultUI: true,
|
||||
disableDoubleClickZoom: true,
|
||||
mapTypeId: google.maps.MapTypeId[getMapType()],
|
||||
noClear: true,
|
||||
scrollwheel: !self.options.zoomOnlyWhenFocused,
|
||||
zoom: self.zoom
|
||||
})
|
||||
self.geocoder = new MaplibreGeocoder({
|
||||
forwardGeocode: forwardGeocode,
|
||||
reverseGeocode: reverseGeocode,
|
||||
})
|
||||
/*
|
||||
map.addControl(self.geocoder, {
|
||||
maplibregl
|
||||
});
|
||||
*/
|
||||
that.map.on('click', clickMap)
|
||||
that.map.on('zoom', zoomChanged)
|
||||
that.map.on('idle', mapChanged)
|
||||
that.map.on('moveend', boundsChanged)
|
||||
that.map.on('dragend', boundsChanged)
|
||||
that.map.on('zoomend', boundsChanged)
|
||||
/*
|
||||
that.map.on('resize', () => {
|
||||
that.resizeMap()
|
||||
})
|
||||
*/
|
||||
/*
|
||||
google.maps.event.addListener(self.map, 'bounds_changed', boundsChanged);
|
||||
google.maps.event.addListener(self.map, 'center_changed', centerChanged);
|
||||
google.maps.event.addListener(self.map, 'click', clickMap);
|
||||
google.maps.event.addListener(self.map, 'idle', mapChanged);
|
||||
google.maps.event.addListener(self.map, 'zoom_changed', zoomChanged);
|
||||
google.maps.event.trigger(self.map, 'resize');
|
||||
*/
|
||||
|
||||
// needed to get mouse x/y coordinates on marker mouseover,
|
||||
// see http://code.google.com/p/gmaps-api-issues/issues/detail?id=2342
|
||||
/*
|
||||
that.overlayView = new google.maps.OverlayView();
|
||||
that.overlayView.setMap(self.map);
|
||||
that.overlayView.draw = function () {
|
||||
|
|
@ -1002,9 +870,7 @@ Ox.Map = function(options, self) {
|
|||
}
|
||||
}
|
||||
that.overlayView.draw();
|
||||
*/
|
||||
|
||||
that.map.on('load', () => {
|
||||
Ox.forEach(self.$controls, function($control) {
|
||||
$control.appendTo(self.$map);
|
||||
});
|
||||
|
|
@ -1025,7 +891,6 @@ Ox.Map = function(options, self) {
|
|||
self.map.setZoom(self.minZoom);
|
||||
} else {
|
||||
self.map.fitBounds(mapBounds);
|
||||
|
||||
}
|
||||
}
|
||||
if (self.map.getZoom() < self.minZoom) {
|
||||
|
|
@ -1034,23 +899,23 @@ Ox.Map = function(options, self) {
|
|||
}
|
||||
updateFormElements();
|
||||
|
||||
that.resizeMap()
|
||||
self.loaded = true;
|
||||
self.boundsChanged = true;
|
||||
that.triggerEvent('load');
|
||||
})
|
||||
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
function isEmpty(bounds) {
|
||||
return bounds._sw.lat == bounds._ne.lat
|
||||
&& bounds._sw.lng == bounds._ne.lng;
|
||||
// Google's bounds.isEmpty() is not reliable
|
||||
var southWest = bounds.getSouthWest(),
|
||||
northEast = bounds.getNorthEast();
|
||||
return southWest.lat() == northEast.lat()
|
||||
&& southWest.lng() == northEast.lng();
|
||||
}
|
||||
|
||||
function isLoaded() {
|
||||
return window.maplibregl && window.maplibregl.maps && window.maplibregl.LngLat;
|
||||
return window.google && window.google.maps && window.google.maps.LatLng;
|
||||
}
|
||||
|
||||
function mapChanged() {
|
||||
|
|
@ -1062,11 +927,12 @@ Ox.Map = function(options, self) {
|
|||
self.boundsChanged = false;
|
||||
return
|
||||
}
|
||||
var south = bounds._sw.lat,
|
||||
west = bounds._sw.lng,
|
||||
north = bounds._ne.lat,
|
||||
east = bounds._ne.lng;
|
||||
|
||||
var southWest = bounds.getSouthWest(),
|
||||
northEast = bounds.getNorthEast(),
|
||||
south = southWest.lat(),
|
||||
west = southWest.lng(),
|
||||
north = northEast.lat(),
|
||||
east = northEast.lng();
|
||||
self.options.places({
|
||||
keys: self.placeKeys,
|
||||
query: {
|
||||
|
|
@ -1149,24 +1015,22 @@ Ox.Map = function(options, self) {
|
|||
}
|
||||
|
||||
function parseGeodata(data) {
|
||||
console.log("parseGeodata", data)
|
||||
// FIXME: data is geojson Feature with Polygon geometry now
|
||||
var bounds = data.bounds || data.geometry.bounds || data.geometry.viewport,
|
||||
northEast = bounds._ne,
|
||||
southWest = bounds._sw,
|
||||
var bounds = data.geometry.bounds || data.geometry.viewport,
|
||||
northEast = bounds.getNorthEast(),
|
||||
southWest = bounds.getSouthWest(),
|
||||
place = {
|
||||
alternativeNames: [],
|
||||
components: data.address_components,
|
||||
countryCode: getCountryCode(data.address_components),
|
||||
east: northEast.lng,
|
||||
east: northEast.lng(),
|
||||
editable: self.options.editable,
|
||||
fullGeoname: getFullGeoname(data.address_components),
|
||||
id: '_' + Ox.encodeBase32(Ox.uid()),
|
||||
map: that,
|
||||
north: northEast.lat,
|
||||
south: southWest.lat,
|
||||
north: northEast.lat(),
|
||||
south: southWest.lat(),
|
||||
type: getType(data.address_components[0].types),
|
||||
west: southWest.lng
|
||||
west: southWest.lng()
|
||||
};
|
||||
place.geoname = data.formatted_address || place.fullGeoname;
|
||||
place.name = (place.geoname || place.fullGeoname).split(', ')[0];
|
||||
|
|
@ -1474,8 +1338,8 @@ Ox.Map = function(options, self) {
|
|||
// so we create properly named properties, for json encoding
|
||||
if (data.latLng) {
|
||||
data.latLng = {
|
||||
lat: data.latLng.lat,
|
||||
lng: data.latLng.lng
|
||||
lat: data.latLng.lat(),
|
||||
lng: data.latLng.lng()
|
||||
}
|
||||
}
|
||||
data.results.forEach(function(result) {
|
||||
|
|
@ -1483,20 +1347,20 @@ Ox.Map = function(options, self) {
|
|||
if (result.geometry[key]) {
|
||||
result.geometry[key] = {
|
||||
northEast: {
|
||||
lat: result.geometry[key]._ne.lat,
|
||||
lng: result.geometry[key]._ne.lng
|
||||
lat: result.geometry[key].getNorthEast().lat(),
|
||||
lng: result.geometry[key].getNorthEast().lng()
|
||||
},
|
||||
southWest: {
|
||||
lat: result.geometry[key]._sw.lat,
|
||||
lng: result.geometry[key]._sw.lng
|
||||
lat: result.geometry[key].getSouthWest().lat(),
|
||||
lng: result.geometry[key].getSouthWest().lng()
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
if (result.geometry.location) {
|
||||
result.geometry.location = {
|
||||
lat: result.geometry.location.lat,
|
||||
lng: result.geometry.location.lng
|
||||
lat: result.geometry.location.lat(),
|
||||
lng: result.geometry.location.lng()
|
||||
}
|
||||
}
|
||||
});
|
||||
|
|
@ -1538,7 +1402,7 @@ Ox.Map = function(options, self) {
|
|||
}
|
||||
|
||||
function zoomChanged() {
|
||||
var zoom = parseInt(self.map.getZoom());
|
||||
var zoom = self.map.getZoom();
|
||||
if (zoom < self.minZoom) {
|
||||
self.map.setZoom(self.minZoom);
|
||||
} else if (self.maxZoom && zoom > self.maxZoom) {
|
||||
|
|
@ -1579,7 +1443,8 @@ Ox.Map = function(options, self) {
|
|||
lng <n> Longitude
|
||||
@*/
|
||||
that.getCenter = function() {
|
||||
return self.map.getCenter();
|
||||
var center = self.map.getCenter();
|
||||
return {lat: center.lat(), lng: center.lng()};
|
||||
};
|
||||
|
||||
/*@
|
||||
|
|
@ -1679,7 +1544,7 @@ Ox.Map = function(options, self) {
|
|||
});
|
||||
updateFormElements();
|
||||
Ox.Log('Map', 'triggering google maps resize event, height', self.options.height)
|
||||
self.map.triggerRepaint()
|
||||
google.maps.event.trigger(self.map, 'resize');
|
||||
// self.map.setCenter(center);
|
||||
}
|
||||
return that;
|
||||
|
|
@ -1693,7 +1558,7 @@ Ox.Map = function(options, self) {
|
|||
lng <n> Longitude
|
||||
@*/
|
||||
that.setCenter = function(center) {
|
||||
self.map.setCenter(new maplibregl.LngLat(center.lng, center.lat));
|
||||
self.map.setCenter(new google.maps.LatLng(center.lat, center.lng));
|
||||
return that;
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -42,32 +42,16 @@ Ox.MapMarker = function(options) {
|
|||
Ox.forEach(options, function(val, key) {
|
||||
that[key] = val;
|
||||
});
|
||||
setColor()
|
||||
const element = document.createElement('div')
|
||||
element.style.border = '2px solid black'
|
||||
element.style.borderRadius = '50px'
|
||||
element.style.backgroundColor = '#' + Ox.toHex(that.color)
|
||||
element.style.width = '16px'
|
||||
element.style.height = '16px'
|
||||
that.marker = new maplibregl.Marker({
|
||||
that.marker = new google.maps.Marker({
|
||||
raiseOnDrag: false,
|
||||
shape: {coords: [8, 8, 8], type: 'circle'},
|
||||
element: element,
|
||||
shape: {coords: [8, 8, 8], type: 'circle'}
|
||||
//title: that.place.name,
|
||||
//zIndex: 1000
|
||||
});
|
||||
that.tooltip = new maplibregl.Popup({
|
||||
closeButton: false,
|
||||
closeOnClick: false,
|
||||
className: 'tooltip'
|
||||
});
|
||||
that.tooltip.addClass
|
||||
|
||||
setOptions();
|
||||
|
||||
function click(event) {
|
||||
event.preventDefault()
|
||||
event.stopPropagation()
|
||||
function click() {
|
||||
var key = that.map.getKey(),
|
||||
place, bounds, southWest, northEast;
|
||||
if (!that.place.selected) {
|
||||
|
|
@ -78,9 +62,9 @@ Ox.MapMarker = function(options) {
|
|||
place = that.map.getSelectedPlace();
|
||||
}
|
||||
if (place) {
|
||||
bounds = new maplibregl.LngLatBounds(
|
||||
new maplibregl.LngLatBounds(place.west, place.south),
|
||||
new maplibregl.LngLatBounds(place.east, place.north)
|
||||
bounds = new google.maps.LatLngBounds(
|
||||
new google.maps.LatLng(place.south, place.west),
|
||||
new google.maps.LatLng(place.north, place.east)
|
||||
);
|
||||
bounds = bounds.union(that.place.bounds);
|
||||
southWest = bounds.getSouthWest();
|
||||
|
|
@ -95,10 +79,10 @@ Ox.MapMarker = function(options) {
|
|||
map: that.map,
|
||||
name: '',
|
||||
type: 'feature',
|
||||
south: southWest.lat,
|
||||
west: southWest.lng,
|
||||
north: northEast.lat,
|
||||
east: northEast.lng
|
||||
south: southWest.lat(),
|
||||
west: southWest.lng(),
|
||||
north: northEast.lat(),
|
||||
east: northEast.lng()
|
||||
}));
|
||||
} else {
|
||||
that.map.options({selected: that.place.id});
|
||||
|
|
@ -123,11 +107,11 @@ Ox.MapMarker = function(options) {
|
|||
function drag(e) {
|
||||
var northSouth = (that.place.north - that.place.south) / 2,
|
||||
lat = Ox.limit(
|
||||
e.lngLat.lat,
|
||||
e.latLng.lat(),
|
||||
Ox.MIN_LATITUDE + northSouth,
|
||||
Ox.MAX_LATITUDE - northSouth
|
||||
),
|
||||
lng = e.lngLat.lng,
|
||||
lng = e.latLng.lng(),
|
||||
span = Math.min(
|
||||
that.place.sizeEastWest * Ox.getDegreesPerMeter(lat) / 2, 179.99999999
|
||||
),
|
||||
|
|
@ -143,7 +127,9 @@ Ox.MapMarker = function(options) {
|
|||
}
|
||||
Ox.Log('Map', 'west', that.place.west, 'east', that.place.east, 'span', span);
|
||||
that.place.update();
|
||||
that.marker.setLngLat(that.place.center)
|
||||
that.marker.setOptions({
|
||||
position: that.place.center
|
||||
});
|
||||
that.place.rectangle.update();
|
||||
}
|
||||
|
||||
|
|
@ -195,30 +181,35 @@ Ox.MapMarker = function(options) {
|
|||
c.context.strokeStyle = 'rgb(' + border.join(', ') + ')';
|
||||
c.context.arc(r, r, r - 1, 0, 360);
|
||||
c.context.stroke();
|
||||
callback(new maplibregl.MarkerImage(
|
||||
callback(new google.maps.MarkerImage(
|
||||
c.canvas.toDataURL(),
|
||||
new maplibregl.Size(options.size, options.size),
|
||||
new maplibregl.Point(0, 0),
|
||||
new maplibregl.Point(r, r)
|
||||
new google.maps.Size(options.size, options.size),
|
||||
new google.maps.Point(0, 0),
|
||||
new google.maps.Point(r, r)
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
function mouseover(e) {
|
||||
that.tooltip.setLngLat(that.place.center).setHTML(
|
||||
'<div style="display: flex; gap: 8px; margin: 2px 2px"><img src="' + Ox.getFlagByGeoname(that.place.geoname, 16)
|
||||
+ '" style="border-radius: 4px;margin: auto"/>'
|
||||
+ '<div style="font-size: 9px;">'
|
||||
+ that.map.options('markerTooltip')(that.place) + '</div></div>'
|
||||
).addTo(that.map.map);
|
||||
var offset = that.map.offset(),
|
||||
xy = that.map.overlayView.getProjection()
|
||||
.fromLatLngToContainerPixel(e.latLng);
|
||||
that.tooltip.show(
|
||||
offset.left + Math.round(xy.x) - 4,
|
||||
offset.top + Math.round(xy.y) + 20
|
||||
);
|
||||
}
|
||||
|
||||
function mouseout() {
|
||||
that.tooltip.remove();
|
||||
that.tooltip.hide();
|
||||
}
|
||||
|
||||
function setColor() {
|
||||
var color = that.map.options('markerColor');
|
||||
function setOptions() {
|
||||
// workaround to prevent marker from appearing twice
|
||||
// after setting draggable from true to false (google maps bug)
|
||||
var fix = that.marker.getDraggable() && !that.place.editing,
|
||||
color = that.map.options('markerColor'),
|
||||
size = that.map.options('markerSize');
|
||||
//Ox.Log('Map', 'setOptions, that.map: ', that.map)
|
||||
if (color == 'auto') {
|
||||
that.color = typeColor[that.place.type] || typeColor['mapPlaceFeatureColor'];
|
||||
|
|
@ -227,15 +218,6 @@ Ox.MapMarker = function(options) {
|
|||
} else {
|
||||
that.color = color(that.place);
|
||||
}
|
||||
}
|
||||
|
||||
function setOptions() {
|
||||
// workaround to prevent marker from appearing twice
|
||||
// after setting draggable from true to false (google maps bug)
|
||||
var fix = false, // that.marker.getDraggable() && !that.place.editing,
|
||||
size = that.map.options('markerSize');
|
||||
//Ox.Log('Map', 'setOptions, that.map: ', that.map)
|
||||
setColor()
|
||||
if (size == 'auto') {
|
||||
that.size = 8;
|
||||
Ox.forEach(areaSize, function(size, area) {
|
||||
|
|
@ -250,46 +232,50 @@ Ox.MapMarker = function(options) {
|
|||
} else {
|
||||
that.size = size(that.place);
|
||||
}
|
||||
/* fixme, some of those can be set some not
|
||||
that.marker.setOptions({
|
||||
// fixme: cursor remains pointer
|
||||
cursor: that.place.editing ? 'move' : 'pointer',
|
||||
draggable: that.place.editing,
|
||||
element: Ox.MapMarkerImage({
|
||||
icon: Ox.MapMarkerImage({
|
||||
color: that.color,
|
||||
mode: that.place.editing ? 'editing' :
|
||||
that.place.selected ? 'selected' : 'normal',
|
||||
size: that.size,
|
||||
type: that.place.id[0] == '_' ? 'result' : 'place'
|
||||
}),
|
||||
})
|
||||
*/
|
||||
//that.marker._color = that.color;
|
||||
that.marker._element.style.cursor = that.place.editing ? 'move' : 'pointer';
|
||||
that.marker.setDraggable(that.place.editing);
|
||||
that.marker.setLngLat(that.place.center);
|
||||
position: that.place.center
|
||||
});
|
||||
if (fix) {
|
||||
that.marker.setVisible(false);
|
||||
setTimeout(function() {
|
||||
that.marker.setVisible(true);
|
||||
}, 0);
|
||||
}
|
||||
setTooltip();
|
||||
}
|
||||
|
||||
function setTooltip() {
|
||||
that.tooltip && that.tooltip.remove();
|
||||
that.tooltip = Ox.Tooltip({
|
||||
title: '<img src="'
|
||||
+ Ox.getFlagByGeoname(that.place.geoname, 16)
|
||||
+ '" style="float: left; width: 16px; height: 16px; margin: 1px 0 1px -1px; border-radius: 4px"/>'
|
||||
+ '<div style="float: left; margin: 4px -1px 0 4px; font-size: 9px;">'
|
||||
+ that.map.options('markerTooltip')(that.place) + '</div>'
|
||||
})
|
||||
.addClass('OxMapMarkerTooltip');
|
||||
}
|
||||
|
||||
/*@
|
||||
add <f> add to map
|
||||
() -> <f> add to map, returns MapMarker
|
||||
@*/
|
||||
that.add = function() {
|
||||
that.marker.addTo(that.map.map);
|
||||
const element = that.marker.getElement()
|
||||
if(element) {
|
||||
element.addEventListener('click', click)
|
||||
element.addEventListener('dblclick', dblclick)
|
||||
element.addEventListener('mouseover', mouseover)
|
||||
element.addEventListener('mouseout', mouseout)
|
||||
}
|
||||
that.marker.setMap(that.map.map);
|
||||
google.maps.event.addListener(that.marker, 'click', click);
|
||||
google.maps.event.addListener(that.marker, 'dblclick', dblclick);
|
||||
google.maps.event.addListener(that.marker, 'mouseover', mouseover);
|
||||
google.maps.event.addListener(that.marker, 'mouseout', mouseout);
|
||||
return that;
|
||||
};
|
||||
|
||||
|
|
@ -299,9 +285,9 @@ Ox.MapMarker = function(options) {
|
|||
@*/
|
||||
that.edit = function() {
|
||||
setOptions();
|
||||
that.marker.on('dragstart', dragstart);
|
||||
that.marker.on('drag', drag);
|
||||
that.marker.on('dragend', dragend);
|
||||
google.maps.event.addListener(that.marker, 'dragstart', dragstart);
|
||||
google.maps.event.addListener(that.marker, 'drag', drag);
|
||||
google.maps.event.addListener(that.marker, 'dragend', dragend);
|
||||
return that;
|
||||
};
|
||||
|
||||
|
|
@ -310,12 +296,8 @@ Ox.MapMarker = function(options) {
|
|||
() -> <f> remove marker from map, returns MapMarker
|
||||
@*/
|
||||
that.remove = function() {
|
||||
that.marker.remove();
|
||||
//that.marker.off('dragstart');
|
||||
//that.marker.off('drag');
|
||||
//that.marker.off('dragend');
|
||||
//fixme does this work to remove all events?
|
||||
that.marker.off();
|
||||
that.marker.setMap(null);
|
||||
google.maps.event.clearListeners(that.marker);
|
||||
return that;
|
||||
};
|
||||
|
||||
|
|
@ -324,9 +306,9 @@ Ox.MapMarker = function(options) {
|
|||
() -> <f> clear edit listeners, returns MapMarker
|
||||
@*/
|
||||
that.submit = function() {
|
||||
that.marker.off('dragstart');
|
||||
that.marker.off('drag');
|
||||
that.marker.off('dragend');
|
||||
google.maps.event.clearListeners(that.marker, 'dragstart');
|
||||
google.maps.event.clearListeners(that.marker, 'drag');
|
||||
google.maps.event.clearListeners(that.marker, 'dragend');
|
||||
return that;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -50,10 +50,12 @@ Ox.MapMarkerImage = (function() {
|
|||
c.context.strokeStyle = 'rgba(' + border.join(', ') + ')';
|
||||
c.context.arc(r, r, r - 1, 0, 360);
|
||||
c.context.stroke();
|
||||
cache[index] = document.createElement('img')
|
||||
cache[index].src = c.canvas.toDataURL()
|
||||
cache[index].width = options.size
|
||||
cache[index].height = options.size
|
||||
cache[index] = new google.maps.MarkerImage(
|
||||
c.canvas.toDataURL(),
|
||||
new google.maps.Size(options.size, options.size),
|
||||
new google.maps.Point(0, 0),
|
||||
new google.maps.Point(r, r)
|
||||
);
|
||||
}
|
||||
|
||||
return cache[index];
|
||||
|
|
|
|||
|
|
@ -44,24 +44,21 @@ Ox.MapPlace = function(options) {
|
|||
update();
|
||||
|
||||
function update(updateMarker) {
|
||||
if (that.east < 0 && that.west > 0) {
|
||||
that.east += 360;
|
||||
}
|
||||
that.points = {
|
||||
ne: new maplibregl.LngLat(that.east, that.north),
|
||||
sw: new maplibregl.LngLat(that.west, that.south)
|
||||
ne: new google.maps.LatLng(that.north, that.east),
|
||||
sw: new google.maps.LatLng(that.south, that.west)
|
||||
};
|
||||
that.bounds = new maplibregl.LngLatBounds(that.points.sw, that.points.ne);
|
||||
that.bounds = new google.maps.LatLngBounds(that.points.sw, that.points.ne);
|
||||
that.center = that.bounds.getCenter();
|
||||
that.lat = that.center.lat;
|
||||
that.lng = that.center.lng;
|
||||
that.lat = that.center.lat();
|
||||
that.lng = that.center.lng();
|
||||
Ox.extend(that.points, {
|
||||
e: new maplibregl.LngLat(that.east, that.lat),
|
||||
s: new maplibregl.LngLat(that.lng, that.south),
|
||||
se: new maplibregl.LngLat(that.east, that.south),
|
||||
n: new maplibregl.LngLat(that.lng, that.north),
|
||||
nw: new maplibregl.LngLat(that.west, that.north),
|
||||
w: new maplibregl.LngLat(that.west, that.lat)
|
||||
e: new google.maps.LatLng(that.lat, that.east),
|
||||
s: new google.maps.LatLng(that.south, that.lng),
|
||||
se: new google.maps.LatLng(that.south, that.east),
|
||||
n: new google.maps.LatLng(that.north, that.lng),
|
||||
nw: new google.maps.LatLng(that.north, that.west),
|
||||
w: new google.maps.LatLng(that.lat, that.west)
|
||||
});
|
||||
// fixme: use bounds.toSpan()
|
||||
that.sizeNorthSouth = (that.north - that.south)
|
||||
|
|
@ -82,9 +79,8 @@ Ox.MapPlace = function(options) {
|
|||
place: that
|
||||
});
|
||||
} else if (updateMarker) {
|
||||
console.log("fixme update marker")
|
||||
//that.marker.update();
|
||||
//that.rectangle.update();
|
||||
that.marker.update();
|
||||
that.rectangle.update();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,172 +1,5 @@
|
|||
'use strict';
|
||||
|
||||
|
||||
class MapLibreRectangle {
|
||||
constructor(options = {}) {
|
||||
this.id = options.id || 'rectangle-' + Ox.uid();
|
||||
this.bounds = options.bounds;
|
||||
this.draggable = options.draggable || false;
|
||||
this.onclick = options.onclick || null
|
||||
}
|
||||
|
||||
_createRectangle() {
|
||||
const coords = this._getPolygonCoordinates();
|
||||
|
||||
const rectangleGeoJSON = {
|
||||
type: 'Feature',
|
||||
geometry: {
|
||||
type: 'Polygon',
|
||||
coordinates: [coords]
|
||||
},
|
||||
properties: {
|
||||
id: this.id
|
||||
}
|
||||
};
|
||||
this.source = this.map.getSource('rectangles')
|
||||
if (!this.source) {
|
||||
this.map.addSource('rectangles', {
|
||||
type: 'geojson',
|
||||
data: {
|
||||
type: 'FeatureCollection',
|
||||
features: []
|
||||
}
|
||||
});
|
||||
this.source = this.map.getSource('rectangles')
|
||||
|
||||
// Add fill layer
|
||||
if (!this.map.getLayer('rectangles-fill')) {
|
||||
this.map.addLayer({
|
||||
id: 'rectangles-fill',
|
||||
type: 'fill',
|
||||
source: 'rectangles',
|
||||
paint: {
|
||||
'fill-color': '#088',
|
||||
'fill-opacity': 0.3
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// Add outline layer
|
||||
if (!this.map.getLayer('rectangles-outline')) {
|
||||
this.map.addLayer({
|
||||
id: 'rectangles-outline',
|
||||
type: 'line',
|
||||
source: 'rectangles',
|
||||
paint: {
|
||||
'line-color': '#000',
|
||||
'line-width': 2
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
/*
|
||||
this.source._data.features.push(rectangleGeoJSON)
|
||||
this.source.setData(this.source._data)
|
||||
*/
|
||||
}
|
||||
|
||||
_getPolygonCoordinates() {
|
||||
const sw = this.bounds._sw;
|
||||
const ne = this.bounds._ne;
|
||||
|
||||
return [
|
||||
[sw.lng, ne.lat], // NW
|
||||
[ne.lng, ne.lat], // NE
|
||||
[ne.lng, sw.lat], // SE
|
||||
[sw.lng, sw.lat], // SW
|
||||
[sw.lng, ne.lat] // Close polygon
|
||||
];
|
||||
}
|
||||
|
||||
setBounds(bounds) {
|
||||
this.bounds = bounds;
|
||||
const coords = this._getPolygonCoordinates();
|
||||
const updatedData = {
|
||||
type: 'Feature',
|
||||
geometry: {
|
||||
type: 'Polygon',
|
||||
coordinates: [coords]
|
||||
},
|
||||
properties: {
|
||||
id: this.id
|
||||
}
|
||||
};
|
||||
var updated = false;
|
||||
this.source._data.features.forEach(feature => {
|
||||
if (feature.properties.id == this.id) {
|
||||
feature.geometry = updatedData.geometry
|
||||
updated = true
|
||||
}
|
||||
})
|
||||
if (!updated) {
|
||||
this.source._data.features.push(updatedData)
|
||||
}
|
||||
this.source.setData(this.source._data)
|
||||
}
|
||||
|
||||
getBounds() {
|
||||
return this.bounds;
|
||||
}
|
||||
|
||||
_enableDragging() {
|
||||
let isDragging = false;
|
||||
let startPos;
|
||||
|
||||
this.map.on('mousedown', `${this.id}-fill`, (e) => {
|
||||
e.preventDefault();
|
||||
isDragging = true;
|
||||
startPos = e.lngLat;
|
||||
this.map.getCanvas().style.cursor = 'grabbing';
|
||||
});
|
||||
|
||||
this.map.on('mousemove', (e) => {
|
||||
if (!isDragging) return;
|
||||
|
||||
const dx = e.lngLat.lng - startPos.lng;
|
||||
const dy = e.lngLat.lat - startPos.lat;
|
||||
|
||||
const sw = [this.bounds[0][0] + dx, this.bounds[0][1] + dy];
|
||||
const ne = [this.bounds[1][0] + dx, this.bounds[1][1] + dy];
|
||||
|
||||
this.setBounds([sw, ne]);
|
||||
startPos = e.lngLat;
|
||||
});
|
||||
|
||||
this.map.on('mouseup', () => {
|
||||
if (isDragging) {
|
||||
isDragging = false;
|
||||
this.map.getCanvas().style.cursor = '';
|
||||
}
|
||||
});
|
||||
}
|
||||
_enableClicking() {
|
||||
this.map.on('click', `${this.id}-fill`, e => {
|
||||
if (this.onclick) {
|
||||
this.onclick(e)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
remove() {
|
||||
this.source._data.features = this.source._data.features.filter(feature => {
|
||||
return feature.properties.id != this.id
|
||||
})
|
||||
this.source.setData(this.source._data)
|
||||
}
|
||||
|
||||
add() {
|
||||
this.setBounds(this.bounds)
|
||||
}
|
||||
|
||||
addTo(map) {
|
||||
this.map = map;
|
||||
this._createRectangle();
|
||||
if (this.draggable) this._enableDragging();
|
||||
this._enableClicking();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*@
|
||||
Ox.MapRectangle <f> MapRectangle Object
|
||||
(options) -> <o> MapRectangle Object
|
||||
|
|
@ -192,18 +25,10 @@ Ox.MapRectangle = function(options) {
|
|||
/*@
|
||||
rectangle <f> google.maps.Rectangle
|
||||
@*/
|
||||
/*
|
||||
that.rectangle = new google.maps.Rectangle({
|
||||
clickable: true,
|
||||
bounds: that.place.bounds
|
||||
});
|
||||
*/
|
||||
that.rectangle = new MapLibreRectangle({
|
||||
bounds: that.place.bounds,
|
||||
});
|
||||
that.rectangle.addTo(that.map.map);
|
||||
that.rectangle.onclick = click
|
||||
|
||||
/*@
|
||||
markers <a> array of markers
|
||||
@*/
|
||||
|
|
@ -217,9 +42,7 @@ Ox.MapRectangle = function(options) {
|
|||
|
||||
setOptions();
|
||||
|
||||
function click(e) {
|
||||
console.log('rectangle click', e)
|
||||
return
|
||||
function click() {
|
||||
if (
|
||||
that.map.options('editable')
|
||||
&& that.place.editable
|
||||
|
|
@ -241,7 +64,6 @@ Ox.MapRectangle = function(options) {
|
|||
? 'mapPlaceEditingBorder'
|
||||
: 'mapPlaceSelectedBorder'
|
||||
]);
|
||||
/*
|
||||
that.rectangle.setOptions({
|
||||
bounds: that.place.bounds,
|
||||
fillColor: color,
|
||||
|
|
@ -250,24 +72,14 @@ Ox.MapRectangle = function(options) {
|
|||
strokeOpacity: that.place.id[0] == '_' ? 0.5 : 1,
|
||||
strokeWeight: 2
|
||||
});
|
||||
*/
|
||||
/*
|
||||
console.log("fixme", {
|
||||
bounds: that.place.bounds,
|
||||
fillColor: color,
|
||||
fillOpacity: that.place.editing ? 0.1 : 0,
|
||||
strokeColor: color,
|
||||
strokeOpacity: that.place.id[0] == '_' ? 0.5 : 1,
|
||||
strokeWeight: 2
|
||||
});
|
||||
*/
|
||||
}
|
||||
|
||||
/*@
|
||||
add <f> add
|
||||
@*/
|
||||
that.add = function() {
|
||||
that.rectangle.add()
|
||||
that.rectangle.setMap(that.map.map);
|
||||
google.maps.event.addListener(that.rectangle, 'click', click);
|
||||
return that;
|
||||
};
|
||||
|
||||
|
|
@ -287,7 +99,8 @@ Ox.MapRectangle = function(options) {
|
|||
remove <f> remove
|
||||
@*/
|
||||
that.remove = function() {
|
||||
that.rectangle.remove();
|
||||
that.rectangle.setMap(null);
|
||||
google.maps.event.clearListeners(that.rectangle);
|
||||
return that;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -23,7 +23,6 @@ Ox.MapRectangleMarker = function(options) {
|
|||
that[key] = val;
|
||||
});
|
||||
|
||||
/*
|
||||
that.markerImage = new google.maps.MarkerImage
|
||||
that.marker = new google.maps.Marker({
|
||||
cursor: that.position + '-resize',
|
||||
|
|
@ -36,30 +35,20 @@ Ox.MapRectangleMarker = function(options) {
|
|||
position: that.place.points[that.position],
|
||||
raiseOnDrag: false
|
||||
});
|
||||
*/
|
||||
that.marker = new maplibregl.Marker({
|
||||
cursor: that.position + '-resize',
|
||||
draggable: true,
|
||||
element: Ox.MapMarkerImage({
|
||||
mode: 'editing',
|
||||
rectangle: true,
|
||||
type: that.place.id[0] == '_' ? 'result' : 'place'
|
||||
}),
|
||||
});
|
||||
|
||||
function dragstart(e) {
|
||||
Ox.$body.addClass('OxDragging');
|
||||
that.drag = {
|
||||
lat: e.lngLat.lat,
|
||||
lng: e.lngLat.lng
|
||||
lat: e.latLng.lat(),
|
||||
lng: e.latLng.lng()
|
||||
};
|
||||
}
|
||||
|
||||
function drag(e) {
|
||||
// fixme: implement shift+drag (center stays the same)
|
||||
Ox.Log('Map', e.pixel.x, e.pixel.y)
|
||||
var lat = Ox.limit(e.lngLat.lat, Ox.MIN_LATITUDE, Ox.MAX_LATITUDE),
|
||||
lng = e.lngLat.lng;
|
||||
var lat = Ox.limit(e.latLng.lat(), Ox.MIN_LATITUDE, Ox.MAX_LATITUDE),
|
||||
lng = e.latLng.lng();
|
||||
that.drag = {
|
||||
lat: lat,
|
||||
lng: lng
|
||||
|
|
@ -111,7 +100,7 @@ Ox.MapRectangleMarker = function(options) {
|
|||
remove <f> remove
|
||||
@*/
|
||||
that.remove = function() {
|
||||
that.marker.remove();
|
||||
that.marker.setMap(null);
|
||||
google.maps.event.clearListeners(that.marker);
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -1,284 +0,0 @@
|
|||
/* Basics */
|
||||
.maplibregl-ctrl-geocoder,
|
||||
.maplibregl-ctrl-geocoder *,
|
||||
.maplibregl-ctrl-geocoder *:after,
|
||||
.maplibregl-ctrl-geocoder *:before {
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.maplibregl-ctrl-geocoder {
|
||||
font-size: 18px;
|
||||
line-height: 24px;
|
||||
font-family: "Open Sans", "Helvetica Neue", Arial, Helvetica, sans-serif;
|
||||
position: relative;
|
||||
background-color: #fff;
|
||||
width: 100%;
|
||||
min-width: 240px;
|
||||
z-index: 1;
|
||||
border-radius: 4px;
|
||||
transition: width 0.25s, min-width 0.25s;
|
||||
}
|
||||
|
||||
.maplibregl-ctrl-geocoder--input {
|
||||
font: inherit;
|
||||
width: 100%;
|
||||
border: 0;
|
||||
background-color: transparent;
|
||||
margin: 0;
|
||||
height: 50px;
|
||||
color: #404040; /* fallback */
|
||||
color: rgba(0, 0, 0, 0.75);
|
||||
padding: 6px 45px;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.maplibregl-ctrl-geocoder--input::-ms-clear {
|
||||
display: none; /* hide input clear button in IE */
|
||||
}
|
||||
|
||||
.maplibregl-ctrl-geocoder--input:focus {
|
||||
color: #404040; /* fallback */
|
||||
color: rgba(0, 0, 0, 0.75);
|
||||
outline: 0;
|
||||
box-shadow: none;
|
||||
outline: thin dotted;
|
||||
}
|
||||
|
||||
.maplibregl-ctrl-geocoder .maplibregl-ctrl-geocoder--pin-right > * {
|
||||
z-index: 2;
|
||||
position: absolute;
|
||||
right: 8px;
|
||||
top: 7px;
|
||||
display: none;
|
||||
}
|
||||
|
||||
.maplibregl-ctrl-geocoder,
|
||||
.maplibregl-ctrl-geocoder .suggestions {
|
||||
box-shadow: 0 0 10px 2px rgba(0, 0, 0, 0.1);
|
||||
}
|
||||
|
||||
/* Collapsed */
|
||||
.maplibregl-ctrl-geocoder.maplibregl-ctrl-geocoder--collapsed {
|
||||
width: 50px;
|
||||
min-width: 50px;
|
||||
transition: width 0.25s, min-width 0.25s;
|
||||
}
|
||||
|
||||
/* Suggestions */
|
||||
.maplibregl-ctrl-geocoder .suggestions {
|
||||
background-color: #fff;
|
||||
border-radius: 4px;
|
||||
left: 0;
|
||||
list-style: none;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
position: absolute;
|
||||
width: 100%;
|
||||
top: 110%; /* fallback */
|
||||
top: calc(100% + 6px);
|
||||
z-index: 1000;
|
||||
overflow: hidden;
|
||||
font-size: 15px;
|
||||
}
|
||||
|
||||
.maplibregl-ctrl-bottom-left .suggestions,
|
||||
.maplibregl-ctrl-bottom-right .suggestions {
|
||||
top: auto;
|
||||
bottom: 100%;
|
||||
}
|
||||
|
||||
.maplibregl-ctrl-geocoder .suggestions > li > a {
|
||||
cursor: default;
|
||||
display: block;
|
||||
padding: 6px 12px;
|
||||
color: #404040;
|
||||
}
|
||||
|
||||
.maplibregl-ctrl-geocoder .suggestions > .active > a,
|
||||
.maplibregl-ctrl-geocoder .suggestions > li > a:hover {
|
||||
color: #404040;
|
||||
background-color: #f3f3f3;
|
||||
text-decoration: none;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.maplibregl-ctrl-geocoder--suggestion {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.maplibre-ctrl-geocoder--suggestion-icon {
|
||||
min-width: 30px;
|
||||
min-height: 24px;
|
||||
max-width: 30px;
|
||||
max-height: 24px;
|
||||
padding-right: 12px;
|
||||
}
|
||||
|
||||
.maplibregl-ctrl-geocoder--suggestion-info {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.maplibregl-ctrl-geocoder--suggestion-match {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.maplibregl-ctrl-geocoder--suggestion-title,
|
||||
.maplibregl-ctrl-geocoder--suggestion-address {
|
||||
text-overflow: ellipsis;
|
||||
overflow: hidden;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.maplibregl-ctrl-geocoder--result {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.maplibre-ctrl-geocoder--result-icon {
|
||||
min-width: 30px;
|
||||
min-height: 24px;
|
||||
max-width: 30px;
|
||||
max-height: 24px;
|
||||
padding-right: 12px;
|
||||
}
|
||||
|
||||
.maplibregl-ctrl-geocoder--result-title {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.maplibregl-ctrl-geocoder--result-title,
|
||||
.maplibregl-ctrl-geocoder--result-address {
|
||||
text-overflow: ellipsis;
|
||||
overflow: hidden;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
/* Icons */
|
||||
.maplibregl-ctrl-geocoder--icon {
|
||||
display: inline-block;
|
||||
vertical-align: middle;
|
||||
speak: none;
|
||||
fill: #757575;
|
||||
top: 15px;
|
||||
}
|
||||
|
||||
.maplibregl-ctrl-geocoder--icon-search {
|
||||
position: absolute;
|
||||
top: 13px;
|
||||
left: 12px;
|
||||
width: 23px;
|
||||
height: 23px;
|
||||
}
|
||||
|
||||
.maplibregl-ctrl-geocoder--button {
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
border: none;
|
||||
cursor: pointer;
|
||||
background: #fff;
|
||||
line-height: 1;
|
||||
}
|
||||
|
||||
.maplibregl-ctrl-geocoder--icon-close {
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
margin-top: 8px;
|
||||
margin-right: 3px;
|
||||
}
|
||||
|
||||
.maplibregl-ctrl-geocoder--button:hover .maplibregl-ctrl-geocoder--icon-close {
|
||||
fill: #909090;
|
||||
}
|
||||
|
||||
.maplibregl-ctrl-geocoder--icon-loading {
|
||||
width: 26px;
|
||||
height: 26px;
|
||||
margin-top: 5px;
|
||||
margin-right: 0px;
|
||||
-moz-animation: rotate 0.8s infinite cubic-bezier(0.45, 0.05, 0.55, 0.95);
|
||||
-webkit-animation: rotate 0.8s infinite cubic-bezier(0.45, 0.05, 0.55, 0.95);
|
||||
animation: rotate 0.8s infinite cubic-bezier(0.45, 0.05, 0.55, 0.95);
|
||||
}
|
||||
|
||||
/* Animation */
|
||||
@-webkit-keyframes rotate {
|
||||
from {
|
||||
-webkit-transform: rotate(0);
|
||||
transform: rotate(0);
|
||||
}
|
||||
to {
|
||||
-webkit-transform: rotate(360deg);
|
||||
transform: rotate(360deg);
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes rotate {
|
||||
from {
|
||||
-webkit-transform: rotate(0);
|
||||
transform: rotate(0);
|
||||
}
|
||||
to {
|
||||
-webkit-transform: rotate(360deg);
|
||||
transform: rotate(360deg);
|
||||
}
|
||||
}
|
||||
|
||||
/* Media queries*/
|
||||
@media screen and (min-width: 640px) {
|
||||
.maplibregl-ctrl-geocoder.maplibregl-ctrl-geocoder--collapsed {
|
||||
width: 36px;
|
||||
min-width: 36px;
|
||||
}
|
||||
|
||||
.maplibregl-ctrl-geocoder {
|
||||
width: 33.3333%;
|
||||
font-size: 15px;
|
||||
line-height: 20px;
|
||||
max-width: 360px;
|
||||
}
|
||||
.maplibregl-ctrl-geocoder .suggestions {
|
||||
font-size: 13px;
|
||||
}
|
||||
|
||||
.maplibregl-ctrl-geocoder--icon {
|
||||
top: 8px;
|
||||
}
|
||||
|
||||
.maplibregl-ctrl-geocoder--icon-close {
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
margin-top: 3px;
|
||||
margin-right: 0;
|
||||
}
|
||||
|
||||
.maplibregl-ctrl-geocoder--icon-search {
|
||||
left: 7px;
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
}
|
||||
|
||||
.maplibregl-ctrl-geocoder--input {
|
||||
height: 36px;
|
||||
padding: 6px 35px;
|
||||
}
|
||||
|
||||
.maplibregl-ctrl-geocoder--icon-loading {
|
||||
width: 26px;
|
||||
height: 26px;
|
||||
margin-top: -2px;
|
||||
margin-right: -5px;
|
||||
}
|
||||
|
||||
.maplibre-gl-geocoder--error {
|
||||
color: #909090;
|
||||
padding: 6px 12px;
|
||||
font-size: 16px;
|
||||
text-align: center;
|
||||
}
|
||||
}
|
||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
|
|
@ -80,33 +80,31 @@ def build_oxjs(downloads=False, geo=False):
|
|||
path = source_path + 'UI/svg/'
|
||||
for filename in [filename for filename in os.listdir(path) if not filename[0] in '._']:
|
||||
svg = read_text(path + filename)
|
||||
svg = re.sub(r'\n\s*', '', svg)
|
||||
svg = re.sub(r'<!--.+?-->', '', svg)
|
||||
svg = re.sub('\n\s*', '', svg)
|
||||
svg = re.sub('<!--.+?-->', '', svg)
|
||||
# end fix
|
||||
ui_images[filename[:-4]] = svg
|
||||
if filename.startswith('symbolLoading'):
|
||||
for theme in themes:
|
||||
theme_svg = re.sub(r'#808080', format_hex(theme_data[theme]['symbolDefaultColor']), svg)
|
||||
theme_svg = re.sub('#808080', format_hex(theme_data[theme]['symbolDefaultColor']), svg)
|
||||
write_file('%sUI/themes/%s/svg/%s' % (dev_path, theme, filename), theme_svg)
|
||||
write_file('%sUI/themes/%s/svg/%s' % (min_path, theme, filename), theme_svg)
|
||||
|
||||
# copy & link
|
||||
ui_files = {'dev': [], 'min': []}
|
||||
css_files = ['maplibre-gl.css', 'maplibre-gl-geocoder.css']
|
||||
for path, dirnames, filenames in os.walk(source_path):
|
||||
for filename in filenames:
|
||||
if '_' not in path and filename[0] not in '._' \
|
||||
and not filename.endswith('~') \
|
||||
and not filename.endswith('.css') \
|
||||
and '/UI/svg' not in path \
|
||||
and (geo or '/Geo/' not in path):
|
||||
if filename.endswith('.css') and filename not in css_files:
|
||||
continue
|
||||
# write copies in min path
|
||||
source = os.path.join(path, filename)
|
||||
is_jquery = re.search(r'^jquery-[\d\.]+\.js$', filename)
|
||||
is_jquery_min = re.search(r'^jquery-[\d\.]+\.min\.js$', filename)
|
||||
is_jquery_plugin = re.search(r'^jquery\..*?\.js$', filename)
|
||||
is_jsonc = re.search(r'\.jsonc$', filename)
|
||||
is_jquery = re.search('^jquery-[\d\.]+\.js$', filename)
|
||||
is_jquery_min = re.search('^jquery-[\d\.]+\.min\.js$', filename)
|
||||
is_jquery_plugin = re.search('^jquery\..*?\.js$', filename)
|
||||
is_jsonc = re.search('\.jsonc$', filename)
|
||||
if is_jquery or is_jquery_min:
|
||||
target = os.path.join(path.replace(source_path, min_path), 'jquery.js')
|
||||
else:
|
||||
|
|
@ -115,7 +113,7 @@ def build_oxjs(downloads=False, geo=False):
|
|||
ui_files['dev'].append(target.replace(min_path, ''))
|
||||
ui_files['min'].append(target.replace(min_path, ''))
|
||||
if '/Ox/js/' not in source and '/UI/js/' not in source and not is_jquery:
|
||||
if re.match(r'^Ox\..+\.js$', filename) or is_jsonc:
|
||||
if re.match('^Ox\..+\.js$', filename) or is_jsonc:
|
||||
js = read_text(source)
|
||||
print('minifiy and write', filename, target)
|
||||
write_file(target, ox.js.minify(js, '' if is_jsonc else comment))
|
||||
|
|
@ -131,7 +129,7 @@ def build_oxjs(downloads=False, geo=False):
|
|||
if not is_jquery_min:
|
||||
write_link(link_source, link_target)
|
||||
# locales
|
||||
match = re.search(r'/(\w+)/json/locale.(\w+).json', source)
|
||||
match = re.search('/(\w+)/json/locale.(\w+).json', source)
|
||||
if match:
|
||||
module = match.group(1)
|
||||
locale = match.group(2)
|
||||
|
|
@ -184,12 +182,12 @@ def build_oxjs(downloads=False, geo=False):
|
|||
if not js_dir + filename in sum(ox_files, []):
|
||||
ox_files[-1].append(js_dir + filename)
|
||||
js = re.sub(
|
||||
r'Ox.LOCALES = \{\}',
|
||||
'Ox.LOCALES = \{\}',
|
||||
'Ox.LOCALES = ' + json.dumps(locales, indent=4, sort_keys=True),
|
||||
js
|
||||
)
|
||||
js = re.sub(
|
||||
r"Ox.VERSION = '([\d\.]+)'",
|
||||
"Ox.VERSION = '([\d\.]+)'",
|
||||
"Ox.VERSION = '%s'" % version,
|
||||
js
|
||||
)
|
||||
|
|
@ -240,7 +238,7 @@ def build_oxjs(downloads=False, geo=False):
|
|||
data = {
|
||||
# sum(list, []) is flatten
|
||||
'documentation': sorted(sum(ox_files, [])) + sorted(list(filter(
|
||||
lambda x: re.search(r'\.js$', x),
|
||||
lambda x: re.search('\.js$', x),
|
||||
ui_files['dev']
|
||||
)) + ['%s/%s.js' % (x, x) for x in ['Geo', 'Image', 'Unicode']]),
|
||||
'examples': sorted(sum(map(
|
||||
|
|
@ -252,7 +250,7 @@ def build_oxjs(downloads=False, geo=False):
|
|||
)
|
||||
)),
|
||||
list(filter(
|
||||
lambda x: not re.search(r'^[._]', x),
|
||||
lambda x: not re.search('^[._]', x),
|
||||
os.listdir(root_path + 'examples/')
|
||||
))
|
||||
), [])) if os.path.exists(root_path + 'examples/') else (),
|
||||
|
|
@ -266,7 +264,7 @@ def build_oxjs(downloads=False, geo=False):
|
|||
'title': get_title(root_path + 'readme/' + x)
|
||||
},
|
||||
filter(
|
||||
lambda x: not re.search(r'^[._]', x) and re.search(r'\.html$', x),
|
||||
lambda x: not re.search('^[._]', x) and re.search('\.html$', x),
|
||||
os.listdir(root_path + 'readme/')
|
||||
)
|
||||
))
|
||||
|
|
@ -357,7 +355,7 @@ def parse_css(css, values):
|
|||
) for vals in value]
|
||||
)
|
||||
return string
|
||||
return re.sub(r'\$(\w+)(\[\d+\])?', sub, css)
|
||||
return re.sub('\$(\w+)(\[\d+\])?', sub, css)
|
||||
|
||||
def read_file(file):
|
||||
print('reading', file)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue