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
|
||||
find <s|""> Initial query
|
||||
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
|
||||
places <[o]|f|null> Array of, or function that returns, place objects
|
||||
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")
|
||||
lat <n> Latitude 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")
|
||||
north <n> Latitude of the northern 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
|
||||
showControls <b|false> If true, show controls
|
||||
showLabels <b|false> If true, show labels on the map
|
||||
showTypes <b|false> If true, color markers according to place type
|
||||
statusbar <b|false> If true, the map has a statusbar
|
||||
toolbar <b|false> If true, the map has a toolbar
|
||||
zoombar <b|false> If true, the map has a zoombar
|
||||
showStatusbar <b|false> If true, the map has a statusbar
|
||||
showToolbar <b|false> If true, the map has a toolbar
|
||||
showZoombar <b|false> If true, the map has a zoombar
|
||||
zoomOnlyWhenFocused <b|false> If true, scroll-zoom only when focused
|
||||
self <o|{}> Shared private variable
|
||||
# EVENTS -------------------------------------------------------------------
|
||||
|
@ -98,20 +98,22 @@ Ox.Map = function(options, self) {
|
|||
self = self || {};
|
||||
var that = Ox.Element({}, self)
|
||||
.defaults({
|
||||
// fixme: isClickable? hasZoombar?
|
||||
// fixme: isClickable?
|
||||
clickable: false,
|
||||
editable: false,
|
||||
find: '',
|
||||
findPlaceholder: 'Find',
|
||||
keys: [],
|
||||
markerColor: 'auto',
|
||||
markerSize: 'auto',
|
||||
maxMarkers: 100,
|
||||
places: null,
|
||||
selected: '',
|
||||
showControls: false,
|
||||
showLabels: false,
|
||||
showTypes: false,
|
||||
statusbar: false, // FIXME: showStatusbar
|
||||
toolbar: false, // FIXME: showToolbar
|
||||
zoombar: false, // FIXME: showZoombar
|
||||
showStatusbar: false,
|
||||
showToolbar: false,
|
||||
showZoombar: false,
|
||||
zoomOnlyWhenFocused: false
|
||||
// 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.metaKey = false;
|
||||
self.minZoom = getMinZoom();
|
||||
self.placeKeys = [
|
||||
self.placeKeys = Ox.merge([
|
||||
'id', 'name', 'alternativeNames', 'geoname', 'countryCode', 'type',
|
||||
'lat', 'lng', 'south', 'west', 'north', 'east', 'area',
|
||||
'editable'
|
||||
];
|
||||
], self.options.keys);
|
||||
self.resultPlace = null;
|
||||
self.scaleMeters = [
|
||||
50000000, 20000000, 10000000,
|
||||
|
@ -213,7 +230,7 @@ Ox.Map = function(options, self) {
|
|||
];
|
||||
self.shiftKey = false;
|
||||
|
||||
if (self.options.toolbar) {
|
||||
if (self.options.showToolbar) {
|
||||
self.$toolbar = Ox.Bar({
|
||||
size: 24
|
||||
})
|
||||
|
@ -275,23 +292,23 @@ Ox.Map = function(options, self) {
|
|||
self.$map = Ox.Element()
|
||||
.css({
|
||||
left: 0,
|
||||
top: self.options.toolbar * 24 + 'px',
|
||||
top: self.options.showToolbar * 24 + 'px',
|
||||
right: 0,
|
||||
bottom: self.options.zoombar * 16 + self.options.statusbar * 24 + 'px'
|
||||
bottom: self.options.showZoombar * 16 + self.options.showStatusbar * 24 + 'px'
|
||||
})
|
||||
.appendTo(that);
|
||||
|
||||
if (self.options.zoombar) {
|
||||
if (self.options.showZoombar) {
|
||||
self.$zoombar = Ox.Bar({
|
||||
size: 16
|
||||
})
|
||||
.css({
|
||||
bottom: self.options.statusbar * 24 + 'px'
|
||||
bottom: self.options.showStatusbar * 24 + 'px'
|
||||
})
|
||||
.appendTo(that);
|
||||
}
|
||||
|
||||
if (self.options.statusbar) {
|
||||
if (self.options.showStatusbar) {
|
||||
self.$statusbar = Ox.Bar({
|
||||
size: 24
|
||||
})
|
||||
|
@ -438,14 +455,6 @@ Ox.Map = function(options, self) {
|
|||
$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) {
|
||||
initMap();
|
||||
} else if (window.googleCallback) {
|
||||
|
@ -471,6 +480,7 @@ Ox.Map = function(options, self) {
|
|||
place.remove();
|
||||
});
|
||||
self.places = [];
|
||||
/*
|
||||
if (!self.isAsync) {
|
||||
self.options.places.forEach(function(place) {
|
||||
self.places.push(new Ox.MapPlace(Ox.extend({
|
||||
|
@ -478,6 +488,7 @@ Ox.Map = function(options, self) {
|
|||
}, place)));
|
||||
});
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
function addPlaceToMap(place) {
|
||||
|
@ -590,7 +601,7 @@ Ox.Map = function(options, self) {
|
|||
}
|
||||
|
||||
function constructZoomInput() {
|
||||
if (self.options.zoombar) {
|
||||
if (self.options.showZoombar) {
|
||||
self.$zoomInput && self.$zoomInput.remove();
|
||||
self.$zoomInput = Ox.Range({
|
||||
arrows: true,
|
||||
|
@ -634,31 +645,20 @@ Ox.Map = function(options, self) {
|
|||
|
||||
function getMapBounds(callback) {
|
||||
// get initial map bounds
|
||||
var mapBounds;
|
||||
if (!self.isAsync) {
|
||||
self.options.places.forEach(function(place, i) {
|
||||
var bounds = getBounds(place);
|
||||
mapBounds = i == 0 ? bounds : mapBounds.union(bounds);
|
||||
});
|
||||
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)
|
||||
);
|
||||
}
|
||||
self.options.places({}, function(result) {
|
||||
var area = result.data.area;
|
||||
callback(new google.maps.LatLngBounds(
|
||||
new google.maps.LatLng(area.south, area.west),
|
||||
new google.maps.LatLng(area.north, area.east)
|
||||
));
|
||||
});
|
||||
}
|
||||
|
||||
function getMapHeight() {
|
||||
return self.options.height
|
||||
- self.options.statusbar * 24
|
||||
- self.options.toolbar * 24
|
||||
- self.options.zoombar * 16;
|
||||
- self.options.showStatusbar * 24
|
||||
- self.options.showToolbar * 24
|
||||
- self.options.showZoombar * 16;
|
||||
}
|
||||
|
||||
function getMapType() {
|
||||
|
@ -916,67 +916,47 @@ Ox.Map = function(options, self) {
|
|||
west = southWest.lng(),
|
||||
north = northEast.lat(),
|
||||
east = northEast.lng();
|
||||
if (!self.isAsync) {
|
||||
self.places.sort(function(a, b) {
|
||||
var sort = {
|
||||
a: a.selected ? Infinity
|
||||
: bounds.contains(a.center) ? a.area
|
||||
: -Infinity,
|
||||
b: b.selected ? Infinity
|
||||
: bounds.contains(b.center) ? b.area
|
||||
: -Infinity,
|
||||
};
|
||||
return sort.b - sort.a;
|
||||
}).forEach(function(place, i) {
|
||||
if (i < self.options.maxMarkers && !place.visible) {
|
||||
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();
|
||||
} 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();
|
||||
}
|
||||
});
|
||||
} 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;
|
||||
}
|
||||
if (self.centerChanged) {
|
||||
|
@ -1189,13 +1169,12 @@ Ox.Map = function(options, self) {
|
|||
}
|
||||
}
|
||||
function select() {
|
||||
//Ox.print('select...', place)
|
||||
place && place.select();
|
||||
self.options.selected = id;
|
||||
setPlaceControls(place);
|
||||
setStatus();
|
||||
that.triggerEvent('selectplace', place);
|
||||
// FIXME: all these events should rather pass {place: place}
|
||||
that.triggerEvent('selectplace', place); // DEPRECATED
|
||||
that.triggerEvent('select', {place: place});
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -1222,8 +1201,9 @@ Ox.Map = function(options, self) {
|
|||
function setScale() {
|
||||
var metersPerPixel = getMetersPerPixel();
|
||||
Ox.forEach(self.scaleMeters, function(meters) {
|
||||
var scaleWidth = Math.round(meters / metersPerPixel);
|
||||
if (scaleWidth <= self.options.width / 2 - 4) {
|
||||
var mapWidth = self.options.width || that.width(),
|
||||
scaleWidth = Math.round(meters / metersPerPixel);
|
||||
if (scaleWidth <= mapWidth / 2 - 4) {
|
||||
self.$controls.scale
|
||||
.options({
|
||||
title: '\u2190 ' + (
|
||||
|
@ -1241,7 +1221,7 @@ Ox.Map = function(options, self) {
|
|||
function setStatus() {
|
||||
//Ox.Log('Map', 'setStatus()', self.options.selected)
|
||||
var code, country, disabled, place, title;
|
||||
if (self.options.statusbar) {
|
||||
if (self.options.showStatusbar) {
|
||||
place = getSelectedPlace();
|
||||
country = place ? Ox.getCountryByGeoname(place.geoname) : '';
|
||||
code = country ? country.code : 'NTHH';
|
||||
|
@ -1355,13 +1335,13 @@ Ox.Map = function(options, self) {
|
|||
|
||||
function updateFormElements() {
|
||||
var width = that.width();
|
||||
if (self.options.zoombar) {
|
||||
if (self.options.showZoombar) {
|
||||
getMaxZoom(function(zoom) {
|
||||
self.maxZoom = zoom;
|
||||
constructZoomInput();
|
||||
});
|
||||
}
|
||||
if (self.options.statusbar) {
|
||||
if (self.options.showStatusbar) {
|
||||
self.$placeNameInput.options({
|
||||
width: Math.floor((width - 132) / 2)
|
||||
});
|
||||
|
@ -1404,8 +1384,6 @@ Ox.Map = function(options, self) {
|
|||
that.$element.css(key, value + 'px');
|
||||
that.resizeMap();
|
||||
} else if (key == 'places') {
|
||||
// fixme: assumes !self.isAsync
|
||||
//Ox.print('MAP SET OPTIONS PLACES', value);
|
||||
addPlaces();
|
||||
getMapBounds(function(mapBounds) {
|
||||
if (mapBounds) {
|
||||
|
@ -1483,8 +1461,8 @@ Ox.Map = function(options, self) {
|
|||
that.resizeMap = function() {
|
||||
// keep center on resize has been commented out
|
||||
// var center = self.map.getCenter();
|
||||
self.options.height = that.$element.height();
|
||||
self.options.width = that.$element.width();
|
||||
self.options.height = that.height();
|
||||
self.options.width = that.width();
|
||||
// check if map has initialized
|
||||
if (self.map) {
|
||||
self.mapHeight = getMapHeight();
|
||||
|
@ -1496,7 +1474,7 @@ Ox.Map = function(options, self) {
|
|||
height: self.mapHeight + 'px',
|
||||
width: self.options.width + 'px'
|
||||
});
|
||||
self.options.zoombar && self.$zoomInput.options({
|
||||
self.options.showZoombar && self.$zoomInput.options({
|
||||
size: self.options.width
|
||||
});
|
||||
updateFormElements();
|
||||
|
|
Loading…
Reference in a new issue