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:
rolux 2012-04-03 15:25:41 +02:00
parent 1278e39759
commit 9f9c2df862

View file

@ -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();