update Ox.Map, remove non-async code path, deprecate non-standard options and events, change the API to allow for dynamic marker colors and sizes
This commit is contained in:
parent
1278e39759
commit
9f9c2df862
1 changed files with 98 additions and 120 deletions
|
@ -18,6 +18,9 @@ Ox.Map <function> Basic map object
|
||||||
editable <b|false> If true, places are editable
|
editable <b|false> If true, places are editable
|
||||||
find <s|""> Initial query
|
find <s|""> Initial query
|
||||||
findPlaceholder <s|"Find"> Placeholder text for the find input element
|
findPlaceholder <s|"Find"> Placeholder text for the find input element
|
||||||
|
keys <a|[]> Additional place properties to be requested
|
||||||
|
markerColor <[n]|f|s|'auto'> Color of place markers ([r, g, b])
|
||||||
|
markerSize <n|f||s|'auto'> Size of place markers in px
|
||||||
maxMarkers <n|100> Maximum number of markers to be displayed
|
maxMarkers <n|100> Maximum number of markers to be displayed
|
||||||
places <[o]|f|null> Array of, or function that returns, place objects
|
places <[o]|f|null> Array of, or function that returns, place objects
|
||||||
countryCode <s> ISO 3166 country code
|
countryCode <s> ISO 3166 country code
|
||||||
|
@ -26,8 +29,6 @@ Ox.Map <function> Basic map object
|
||||||
geoname <s> Geoname (like "Paris, Île-de-France, France")
|
geoname <s> Geoname (like "Paris, Île-de-France, France")
|
||||||
lat <n> Latitude in degrees
|
lat <n> Latitude in degrees
|
||||||
lng <n> Longitude in degrees
|
lng <n> Longitude in degrees
|
||||||
markerColor <s|"red"> CSS color of the place marker
|
|
||||||
markerSize <n|16> size of the place marker in px
|
|
||||||
name <s> Name (like "Paris")
|
name <s> Name (like "Paris")
|
||||||
north <n> Latitude of the northern boundary in degrees
|
north <n> Latitude of the northern boundary in degrees
|
||||||
south <n> Latitude of the southern boundary in degrees
|
south <n> Latitude of the southern boundary in degrees
|
||||||
|
@ -36,10 +37,9 @@ Ox.Map <function> Basic map object
|
||||||
selected <s|""> Id of the selected place
|
selected <s|""> Id of the selected place
|
||||||
showControls <b|false> If true, show controls
|
showControls <b|false> If true, show controls
|
||||||
showLabels <b|false> If true, show labels on the map
|
showLabels <b|false> If true, show labels on the map
|
||||||
showTypes <b|false> If true, color markers according to place type
|
showStatusbar <b|false> If true, the map has a statusbar
|
||||||
statusbar <b|false> If true, the map has a statusbar
|
showToolbar <b|false> If true, the map has a toolbar
|
||||||
toolbar <b|false> If true, the map has a toolbar
|
showZoombar <b|false> If true, the map has a zoombar
|
||||||
zoombar <b|false> If true, the map has a zoombar
|
|
||||||
zoomOnlyWhenFocused <b|false> If true, scroll-zoom only when focused
|
zoomOnlyWhenFocused <b|false> If true, scroll-zoom only when focused
|
||||||
self <o|{}> Shared private variable
|
self <o|{}> Shared private variable
|
||||||
# EVENTS -------------------------------------------------------------------
|
# EVENTS -------------------------------------------------------------------
|
||||||
|
@ -98,20 +98,22 @@ Ox.Map = function(options, self) {
|
||||||
self = self || {};
|
self = self || {};
|
||||||
var that = Ox.Element({}, self)
|
var that = Ox.Element({}, self)
|
||||||
.defaults({
|
.defaults({
|
||||||
// fixme: isClickable? hasZoombar?
|
// fixme: isClickable?
|
||||||
clickable: false,
|
clickable: false,
|
||||||
editable: false,
|
editable: false,
|
||||||
find: '',
|
find: '',
|
||||||
findPlaceholder: 'Find',
|
findPlaceholder: 'Find',
|
||||||
|
keys: [],
|
||||||
|
markerColor: 'auto',
|
||||||
|
markerSize: 'auto',
|
||||||
maxMarkers: 100,
|
maxMarkers: 100,
|
||||||
places: null,
|
places: null,
|
||||||
selected: '',
|
selected: '',
|
||||||
showControls: false,
|
showControls: false,
|
||||||
showLabels: false,
|
showLabels: false,
|
||||||
showTypes: false,
|
showStatusbar: false,
|
||||||
statusbar: false, // FIXME: showStatusbar
|
showToolbar: false,
|
||||||
toolbar: false, // FIXME: showToolbar
|
showZoombar: false,
|
||||||
zoombar: false, // FIXME: showZoombar
|
|
||||||
zoomOnlyWhenFocused: false
|
zoomOnlyWhenFocused: false
|
||||||
// fixme: width, height
|
// fixme: width, height
|
||||||
})
|
})
|
||||||
|
@ -192,15 +194,30 @@ Ox.Map = function(options, self) {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
self.isAsync = Ox.isFunction(self.options.places);
|
// HANDLE DEPRECATED OPTIONS
|
||||||
|
['statusbar', 'toolbar', 'zoombar'].forEach(function(key) {
|
||||||
|
if (options[key]) {
|
||||||
|
self.options['show' + Ox.toTitleCase(key)] = options[key];
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
if (Ox.isArray(self.options.places)) {
|
||||||
|
self.options.places.forEach(function(place) {
|
||||||
|
if (Ox.isUndefined(place.id)) {
|
||||||
|
place.id = Ox.encodeBase32(Ox.uid());
|
||||||
|
}
|
||||||
|
});
|
||||||
|
self.options.places = Ox.api(self.options.places, {geo: true});
|
||||||
|
}
|
||||||
|
|
||||||
self.mapHeight = getMapHeight();
|
self.mapHeight = getMapHeight();
|
||||||
self.metaKey = false;
|
self.metaKey = false;
|
||||||
self.minZoom = getMinZoom();
|
self.minZoom = getMinZoom();
|
||||||
self.placeKeys = [
|
self.placeKeys = Ox.merge([
|
||||||
'id', 'name', 'alternativeNames', 'geoname', 'countryCode', 'type',
|
'id', 'name', 'alternativeNames', 'geoname', 'countryCode', 'type',
|
||||||
'lat', 'lng', 'south', 'west', 'north', 'east', 'area',
|
'lat', 'lng', 'south', 'west', 'north', 'east', 'area',
|
||||||
'editable'
|
'editable'
|
||||||
];
|
], self.options.keys);
|
||||||
self.resultPlace = null;
|
self.resultPlace = null;
|
||||||
self.scaleMeters = [
|
self.scaleMeters = [
|
||||||
50000000, 20000000, 10000000,
|
50000000, 20000000, 10000000,
|
||||||
|
@ -213,7 +230,7 @@ Ox.Map = function(options, self) {
|
||||||
];
|
];
|
||||||
self.shiftKey = false;
|
self.shiftKey = false;
|
||||||
|
|
||||||
if (self.options.toolbar) {
|
if (self.options.showToolbar) {
|
||||||
self.$toolbar = Ox.Bar({
|
self.$toolbar = Ox.Bar({
|
||||||
size: 24
|
size: 24
|
||||||
})
|
})
|
||||||
|
@ -275,23 +292,23 @@ Ox.Map = function(options, self) {
|
||||||
self.$map = Ox.Element()
|
self.$map = Ox.Element()
|
||||||
.css({
|
.css({
|
||||||
left: 0,
|
left: 0,
|
||||||
top: self.options.toolbar * 24 + 'px',
|
top: self.options.showToolbar * 24 + 'px',
|
||||||
right: 0,
|
right: 0,
|
||||||
bottom: self.options.zoombar * 16 + self.options.statusbar * 24 + 'px'
|
bottom: self.options.showZoombar * 16 + self.options.showStatusbar * 24 + 'px'
|
||||||
})
|
})
|
||||||
.appendTo(that);
|
.appendTo(that);
|
||||||
|
|
||||||
if (self.options.zoombar) {
|
if (self.options.showZoombar) {
|
||||||
self.$zoombar = Ox.Bar({
|
self.$zoombar = Ox.Bar({
|
||||||
size: 16
|
size: 16
|
||||||
})
|
})
|
||||||
.css({
|
.css({
|
||||||
bottom: self.options.statusbar * 24 + 'px'
|
bottom: self.options.showStatusbar * 24 + 'px'
|
||||||
})
|
})
|
||||||
.appendTo(that);
|
.appendTo(that);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (self.options.statusbar) {
|
if (self.options.showStatusbar) {
|
||||||
self.$statusbar = Ox.Bar({
|
self.$statusbar = Ox.Bar({
|
||||||
size: 24
|
size: 24
|
||||||
})
|
})
|
||||||
|
@ -438,14 +455,6 @@ Ox.Map = function(options, self) {
|
||||||
$placeControl.css({opacity: 0}).hide();
|
$placeControl.css({opacity: 0}).hide();
|
||||||
});
|
});
|
||||||
|
|
||||||
if (!self.isAsync) {
|
|
||||||
self.options.places.forEach(function(place) {
|
|
||||||
if (Ox.isUndefined(place.id)) {
|
|
||||||
place.id = Ox.encodeBase32(Ox.uid());
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
if (window.google) {
|
if (window.google) {
|
||||||
initMap();
|
initMap();
|
||||||
} else if (window.googleCallback) {
|
} else if (window.googleCallback) {
|
||||||
|
@ -471,6 +480,7 @@ Ox.Map = function(options, self) {
|
||||||
place.remove();
|
place.remove();
|
||||||
});
|
});
|
||||||
self.places = [];
|
self.places = [];
|
||||||
|
/*
|
||||||
if (!self.isAsync) {
|
if (!self.isAsync) {
|
||||||
self.options.places.forEach(function(place) {
|
self.options.places.forEach(function(place) {
|
||||||
self.places.push(new Ox.MapPlace(Ox.extend({
|
self.places.push(new Ox.MapPlace(Ox.extend({
|
||||||
|
@ -478,6 +488,7 @@ Ox.Map = function(options, self) {
|
||||||
}, place)));
|
}, place)));
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
}
|
}
|
||||||
|
|
||||||
function addPlaceToMap(place) {
|
function addPlaceToMap(place) {
|
||||||
|
@ -590,7 +601,7 @@ Ox.Map = function(options, self) {
|
||||||
}
|
}
|
||||||
|
|
||||||
function constructZoomInput() {
|
function constructZoomInput() {
|
||||||
if (self.options.zoombar) {
|
if (self.options.showZoombar) {
|
||||||
self.$zoomInput && self.$zoomInput.remove();
|
self.$zoomInput && self.$zoomInput.remove();
|
||||||
self.$zoomInput = Ox.Range({
|
self.$zoomInput = Ox.Range({
|
||||||
arrows: true,
|
arrows: true,
|
||||||
|
@ -634,31 +645,20 @@ Ox.Map = function(options, self) {
|
||||||
|
|
||||||
function getMapBounds(callback) {
|
function getMapBounds(callback) {
|
||||||
// get initial map bounds
|
// get initial map bounds
|
||||||
var mapBounds;
|
self.options.places({}, function(result) {
|
||||||
if (!self.isAsync) {
|
var area = result.data.area;
|
||||||
self.options.places.forEach(function(place, i) {
|
callback(new google.maps.LatLngBounds(
|
||||||
var bounds = getBounds(place);
|
new google.maps.LatLng(area.south, area.west),
|
||||||
mapBounds = i == 0 ? bounds : mapBounds.union(bounds);
|
new google.maps.LatLng(area.north, area.east)
|
||||||
});
|
));
|
||||||
callback(mapBounds);
|
});
|
||||||
} else {
|
|
||||||
self.options.places({}, function(result) {
|
|
||||||
callback(getBounds(result.data.area));
|
|
||||||
});
|
|
||||||
}
|
|
||||||
function getBounds(place) {
|
|
||||||
return new google.maps.LatLngBounds(
|
|
||||||
new google.maps.LatLng(place.south, place.west),
|
|
||||||
new google.maps.LatLng(place.north, place.east)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function getMapHeight() {
|
function getMapHeight() {
|
||||||
return self.options.height
|
return self.options.height
|
||||||
- self.options.statusbar * 24
|
- self.options.showStatusbar * 24
|
||||||
- self.options.toolbar * 24
|
- self.options.showToolbar * 24
|
||||||
- self.options.zoombar * 16;
|
- self.options.showZoombar * 16;
|
||||||
}
|
}
|
||||||
|
|
||||||
function getMapType() {
|
function getMapType() {
|
||||||
|
@ -916,67 +916,47 @@ Ox.Map = function(options, self) {
|
||||||
west = southWest.lng(),
|
west = southWest.lng(),
|
||||||
north = northEast.lat(),
|
north = northEast.lat(),
|
||||||
east = northEast.lng();
|
east = northEast.lng();
|
||||||
if (!self.isAsync) {
|
self.options.places({
|
||||||
self.places.sort(function(a, b) {
|
keys: self.placeKeys,
|
||||||
var sort = {
|
query: {
|
||||||
a: a.selected ? Infinity
|
conditions: Ox.merge([
|
||||||
: bounds.contains(a.center) ? a.area
|
{key: 'lat', value: [south, north], operator: '='}
|
||||||
: -Infinity,
|
], spansGlobe() ? [
|
||||||
b: b.selected ? Infinity
|
{key: 'lng', value: [-180, 180], operator: '='}
|
||||||
: bounds.contains(b.center) ? b.area
|
] : crossesDateline() ? [
|
||||||
: -Infinity,
|
{key: 'lng', value: [east, west], operator: '!='}
|
||||||
};
|
] : [
|
||||||
return sort.b - sort.a;
|
{key: 'lng', value: [west, east], operator: '='}
|
||||||
}).forEach(function(place, i) {
|
]),
|
||||||
if (i < self.options.maxMarkers && !place.visible) {
|
operator: '&'
|
||||||
|
},
|
||||||
|
range: [0, self.options.maxMarkers],
|
||||||
|
sort: [{key: 'area', operator: '-'}]
|
||||||
|
}, function(result) {
|
||||||
|
Ox.Log('Map', 'RESULT', result)
|
||||||
|
var ids = [];
|
||||||
|
result.data.items.forEach(function(item, i) {
|
||||||
|
var place = getPlaceById(item.id);
|
||||||
|
if (!place) {
|
||||||
|
self.places.push(
|
||||||
|
new Ox.MapPlace(Ox.extend({
|
||||||
|
map: that
|
||||||
|
}, item)).add()
|
||||||
|
);
|
||||||
|
} else if (!place.visible) {
|
||||||
place.add();
|
place.add();
|
||||||
} else if (i >= self.options.maxMarkers && place.visible) {
|
}
|
||||||
|
ids.push(item.id);
|
||||||
|
});
|
||||||
|
self.places.forEach(function(place) {
|
||||||
|
if (
|
||||||
|
!place.selected && place.visible
|
||||||
|
&& ids.indexOf(place.id) == -1
|
||||||
|
) {
|
||||||
place.remove();
|
place.remove();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
} else {
|
});
|
||||||
self.options.places({
|
|
||||||
keys: self.placeKeys,
|
|
||||||
query: {
|
|
||||||
conditions: Ox.merge([
|
|
||||||
{key: 'lat', value: [south, north], operator: '='}
|
|
||||||
], spansGlobe() ? [
|
|
||||||
{key: 'lng', value: [-180, 180], operator: '='}
|
|
||||||
] : crossesDateline() ? [
|
|
||||||
{key: 'lng', value: [east, west], operator: '!='}
|
|
||||||
] : [
|
|
||||||
{key: 'lng', value: [west, east], operator: '='}
|
|
||||||
]),
|
|
||||||
operator: '&'
|
|
||||||
},
|
|
||||||
range: [0, self.options.maxMarkers],
|
|
||||||
sort: [{key: 'area', operator: '-'}]
|
|
||||||
}, function(result) {
|
|
||||||
Ox.Log('Map', 'RESULT', result)
|
|
||||||
var ids = [];
|
|
||||||
result.data.items.forEach(function(item, i) {
|
|
||||||
var place = getPlaceById(item.id);
|
|
||||||
if (!place) {
|
|
||||||
self.places.push(
|
|
||||||
new Ox.MapPlace(Ox.extend({
|
|
||||||
map: that
|
|
||||||
}, item)).add()
|
|
||||||
);
|
|
||||||
} else if (!place.visible) {
|
|
||||||
place.add();
|
|
||||||
}
|
|
||||||
ids.push(item.id);
|
|
||||||
});
|
|
||||||
self.places.forEach(function(place) {
|
|
||||||
if (
|
|
||||||
!place.selected && place.visible
|
|
||||||
&& ids.indexOf(place.id) == -1
|
|
||||||
) {
|
|
||||||
place.remove();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
|
||||||
self.boundsChanged = false;
|
self.boundsChanged = false;
|
||||||
}
|
}
|
||||||
if (self.centerChanged) {
|
if (self.centerChanged) {
|
||||||
|
@ -1189,13 +1169,12 @@ Ox.Map = function(options, self) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
function select() {
|
function select() {
|
||||||
//Ox.print('select...', place)
|
|
||||||
place && place.select();
|
place && place.select();
|
||||||
self.options.selected = id;
|
self.options.selected = id;
|
||||||
setPlaceControls(place);
|
setPlaceControls(place);
|
||||||
setStatus();
|
setStatus();
|
||||||
that.triggerEvent('selectplace', place);
|
that.triggerEvent('selectplace', place); // DEPRECATED
|
||||||
// FIXME: all these events should rather pass {place: place}
|
that.triggerEvent('select', {place: place});
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -1222,8 +1201,9 @@ Ox.Map = function(options, self) {
|
||||||
function setScale() {
|
function setScale() {
|
||||||
var metersPerPixel = getMetersPerPixel();
|
var metersPerPixel = getMetersPerPixel();
|
||||||
Ox.forEach(self.scaleMeters, function(meters) {
|
Ox.forEach(self.scaleMeters, function(meters) {
|
||||||
var scaleWidth = Math.round(meters / metersPerPixel);
|
var mapWidth = self.options.width || that.width(),
|
||||||
if (scaleWidth <= self.options.width / 2 - 4) {
|
scaleWidth = Math.round(meters / metersPerPixel);
|
||||||
|
if (scaleWidth <= mapWidth / 2 - 4) {
|
||||||
self.$controls.scale
|
self.$controls.scale
|
||||||
.options({
|
.options({
|
||||||
title: '\u2190 ' + (
|
title: '\u2190 ' + (
|
||||||
|
@ -1241,7 +1221,7 @@ Ox.Map = function(options, self) {
|
||||||
function setStatus() {
|
function setStatus() {
|
||||||
//Ox.Log('Map', 'setStatus()', self.options.selected)
|
//Ox.Log('Map', 'setStatus()', self.options.selected)
|
||||||
var code, country, disabled, place, title;
|
var code, country, disabled, place, title;
|
||||||
if (self.options.statusbar) {
|
if (self.options.showStatusbar) {
|
||||||
place = getSelectedPlace();
|
place = getSelectedPlace();
|
||||||
country = place ? Ox.getCountryByGeoname(place.geoname) : '';
|
country = place ? Ox.getCountryByGeoname(place.geoname) : '';
|
||||||
code = country ? country.code : 'NTHH';
|
code = country ? country.code : 'NTHH';
|
||||||
|
@ -1355,13 +1335,13 @@ Ox.Map = function(options, self) {
|
||||||
|
|
||||||
function updateFormElements() {
|
function updateFormElements() {
|
||||||
var width = that.width();
|
var width = that.width();
|
||||||
if (self.options.zoombar) {
|
if (self.options.showZoombar) {
|
||||||
getMaxZoom(function(zoom) {
|
getMaxZoom(function(zoom) {
|
||||||
self.maxZoom = zoom;
|
self.maxZoom = zoom;
|
||||||
constructZoomInput();
|
constructZoomInput();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
if (self.options.statusbar) {
|
if (self.options.showStatusbar) {
|
||||||
self.$placeNameInput.options({
|
self.$placeNameInput.options({
|
||||||
width: Math.floor((width - 132) / 2)
|
width: Math.floor((width - 132) / 2)
|
||||||
});
|
});
|
||||||
|
@ -1404,8 +1384,6 @@ Ox.Map = function(options, self) {
|
||||||
that.$element.css(key, value + 'px');
|
that.$element.css(key, value + 'px');
|
||||||
that.resizeMap();
|
that.resizeMap();
|
||||||
} else if (key == 'places') {
|
} else if (key == 'places') {
|
||||||
// fixme: assumes !self.isAsync
|
|
||||||
//Ox.print('MAP SET OPTIONS PLACES', value);
|
|
||||||
addPlaces();
|
addPlaces();
|
||||||
getMapBounds(function(mapBounds) {
|
getMapBounds(function(mapBounds) {
|
||||||
if (mapBounds) {
|
if (mapBounds) {
|
||||||
|
@ -1483,8 +1461,8 @@ Ox.Map = function(options, self) {
|
||||||
that.resizeMap = function() {
|
that.resizeMap = function() {
|
||||||
// keep center on resize has been commented out
|
// keep center on resize has been commented out
|
||||||
// var center = self.map.getCenter();
|
// var center = self.map.getCenter();
|
||||||
self.options.height = that.$element.height();
|
self.options.height = that.height();
|
||||||
self.options.width = that.$element.width();
|
self.options.width = that.width();
|
||||||
// check if map has initialized
|
// check if map has initialized
|
||||||
if (self.map) {
|
if (self.map) {
|
||||||
self.mapHeight = getMapHeight();
|
self.mapHeight = getMapHeight();
|
||||||
|
@ -1496,7 +1474,7 @@ Ox.Map = function(options, self) {
|
||||||
height: self.mapHeight + 'px',
|
height: self.mapHeight + 'px',
|
||||||
width: self.options.width + 'px'
|
width: self.options.width + 'px'
|
||||||
});
|
});
|
||||||
self.options.zoombar && self.$zoomInput.options({
|
self.options.showZoombar && self.$zoomInput.options({
|
||||||
size: self.options.width
|
size: self.options.width
|
||||||
});
|
});
|
||||||
updateFormElements();
|
updateFormElements();
|
||||||
|
|
Loading…
Add table
Reference in a new issue