some support for async maps

This commit is contained in:
rolux 2011-05-29 11:52:33 +02:00
parent 6bb66b190c
commit a280574033
4 changed files with 130 additions and 68 deletions

View file

@ -378,7 +378,7 @@ Ox.load('UI', {debug: true, hideScreen: true, showScreen: true, theme: 'modern'}
{name: 'Alfred Hitchcock', start: '1899-08-13', end: '1980-04-29', type: 'person'}, {name: 'Alfred Hitchcock', start: '1899-08-13', end: '1980-04-29', type: 'person'},
{name: 'Jorge Luis Borges', start: '1899-08-24', end: '1986-06-14', type: 'person'}, {name: 'Jorge Luis Borges', start: '1899-08-24', end: '1986-06-14', type: 'person'},
{name: 'Luis Bunuel', start: '1900-02-22', end: '1983-07-29', type: 'person'}, {name: 'Luis Buñuel', start: '1900-02-22', end: '1983-07-29', type: 'person'},
{name: 'Jan Oort', start: '1900-04-28', end: '1992-11-05', type: 'person'}, {name: 'Jan Oort', start: '1900-04-28', end: '1992-11-05', type: 'person'},
{name: 'Catherine Hessling', start: '1900-06-22', end: '1979-09-28', type: 'person'}, {name: 'Catherine Hessling', start: '1900-06-22', end: '1979-09-28', type: 'person'},
{name: 'Robert Siodmak', start: '1900-08-08', end: '1973-03-10', type: 'person'}, {name: 'Robert Siodmak', start: '1900-08-08', end: '1973-03-10', type: 'person'},

View file

@ -68,6 +68,7 @@ Ox.load('UI', {debug: true}, function() {
Ox.print('DATA', data) Ox.print('DATA', data)
panel.replaceElement(1, list = new Ox.TreeList({ panel.replaceElement(1, list = new Ox.TreeList({
data: Ox.isEmpty(data) ? [] : { data: Ox.isEmpty(data) ? [] : {
area: data.area,
components: data.components, components: data.components,
countryCode: data.countryCode, countryCode: data.countryCode,
crossesDateline: data.crossesDateline(), crossesDateline: data.crossesDateline(),
@ -78,7 +79,6 @@ Ox.load('UI', {debug: true}, function() {
lng: data.lng, lng: data.lng,
name: data.name, name: data.name,
north: data.north, north: data.north,
size: data.size,
sizeEastWest: data.sizeEastWest, sizeEastWest: data.sizeEastWest,
sizeNorthSouth: data.sizeNorthSouth, sizeNorthSouth: data.sizeNorthSouth,
south: data.south, south: data.south,

View file

@ -411,24 +411,24 @@ Ox.ListMap = function(options, self) {
place.countryCode = country ? country.code : ''; place.countryCode = country ? country.code : '';
self.selectedPlace = self.selectedPlace.substr(1); // fixme: safe? self.selectedPlace = self.selectedPlace.substr(1); // fixme: safe?
place.id = self.selectedPlace; place.id = self.selectedPlace;
if (Ox.isArray(self.options.places)) { //if (Ox.isArray(self.options.places)) {
self.options.places.push(place); self.options.places.push(place);
self.$list.options({ self.$list.options({
items: Ox.clone(self.options.places), items: Ox.clone(self.options.places),
selected: [place.id] selected: [place.id]
}); });
setStatus(); setStatus();
} //}
self.$map.addPlace(place); self.$map.addPlace(place);
self.$placeButton.options({title: 'Remove Place'}); self.$placeButton.options({title: 'Remove Place'});
that.triggerEvent('addplace', {place: place}); that.triggerEvent('addplace', {place: place});
} else if (title == 'Remove Place') { } else if (title == 'Remove Place') {
var index = Ox.getPositionById(self.options.places, self.selectedPlace); var index = Ox.getPositionById(self.options.places, self.selectedPlace);
if (Ox.isArray(self.options.places)) { //if (Ox.isArray(self.options.places)) {
self.options.places.splice(index, 1); self.options.places.splice(index, 1);
self.$list.options({items: Ox.clone(self.options.places)}); self.$list.options({items: Ox.clone(self.options.places)});
setStatus(); setStatus();
} //}
self.$map.removePlace(); self.$map.removePlace();
self.$placeButton.options({title: 'Add Place'}); self.$placeButton.options({title: 'Add Place'});
that.triggerEvent('removeplace', {place: place}); that.triggerEvent('removeplace', {place: place});

View file

@ -15,8 +15,8 @@ Ox.Map <function> Basic map object
clickable <b|false> If true, clicking on the map finds a place clickable <b|false> If true, clicking on the map finds a place
editable <b|false> If true, places are editable editable <b|false> If true, places are editable
findPlaceholder <s|"Find"> Placeholder text for the find input element findPlaceholder <s|"Find"> Placeholder text for the find input element
markers <n|100> Maximum number of markers to be displayed maxMarkers <n|100> Maximum number of markers to be displayed
places <[o]|[]> Array of 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
east <n> Longitude of the eastern boundary in degrees east <n> Longitude of the eastern boundary in degrees
editable <b|false> If true, the place is editable editable <b|false> If true, the place is editable
@ -94,8 +94,8 @@ Ox.Map = function(options, self) {
clickable: false, clickable: false,
editable: false, editable: false,
findPlaceholder: 'Find', findPlaceholder: 'Find',
markers: 100, maxMarkers: 100,
places: [], places: null,
selected: null, selected: null,
showControls: false, showControls: false,
showLabels: false, showLabels: false,
@ -173,6 +173,7 @@ Ox.Map = function(options, self) {
key_z: undo key_z: undo
}); });
self.isAsync = Ox.isFunction(self.options.places);
self.mapHeight = getMapHeight(); self.mapHeight = getMapHeight();
self.minZoom = getMinZoom(); self.minZoom = getMinZoom();
self.scaleMeters = [ self.scaleMeters = [
@ -352,6 +353,14 @@ Ox.Map = function(options, self) {
.addClass('OxMapLabel') .addClass('OxMapLabel')
.css({right: '4px', top: '4px'}); .css({right: '4px', top: '4px'});
if (!self.isAsync) {
self.options.places.forEach(function(place) {
if (Ox.isUndefined(place.id)) {
place.id = Ox.encodeBase32(Ox.uid());
}
});
}
if (!window.googleCallback) { if (!window.googleCallback) {
window.googleCallback = function() { window.googleCallback = function() {
delete window.googleCallback; delete window.googleCallback;
@ -507,6 +516,28 @@ 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));
});
}
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.statusbar * 24 -
@ -651,53 +682,48 @@ Ox.Map = function(options, self) {
} }
function initMap() { function initMap() {
var mapBounds;
updateFormElements(); getMapBounds(function(mapBounds) {
self.elevationService = new google.maps.ElevationService(); Ox.print('init', mapBounds.getSouthWest(), mapBounds.getNorthEast(), mapBounds.getCenter())
self.geocoder = new google.maps.Geocoder();
self.maxZoomService = new google.maps.MaxZoomService(); updateFormElements();
self.places = [];
self.options.places.forEach(function(place, i) { self.elevationService = new google.maps.ElevationService();
var bounds = new google.maps.LatLngBounds( self.geocoder = new google.maps.Geocoder();
new google.maps.LatLng(place.south, place.west), self.maxZoomService = new google.maps.MaxZoomService();
new google.maps.LatLng(place.north, place.east)
); self.center = mapBounds ? mapBounds.getCenter() : new google.maps.LatLng(0, 0);
if (Ox.isUndefined(place.id)) { self.zoom = 1; // fixme: should depend on height
place.id = Ox.uid(); that.map = self.map = new google.maps.Map(self.$map.$element[0], {
center: self.center,
disableDefaultUI: true,
disableDoubleClickZoom: true,
mapTypeId: google.maps.MapTypeId[getMapType()],
zoom: self.zoom
});
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.addListenerOnce(self.map, 'tilesloaded', tilesLoaded);
mapBounds && self.map.fitBounds(mapBounds);
self.places = [];
if (!self.isAsync) {
self.options.places.forEach(function(place, i) {
self.places[i] = new Ox.MapPlace(Ox.extend({
map: that
}, place));
});
} }
mapBounds = i == 0 ? bounds : mapBounds.union(bounds); google.maps.event.trigger(self.map, 'resize');
//that.gainFocus();
that.triggerEvent('load');
}); });
//Ox.print('BOUNDS', mapBounds.getSouthWest(), mapBounds.getNorthEast(), mapBounds.getCenter())
self.center = mapBounds ? mapBounds.getCenter() : new google.maps.LatLng(0, 0);
self.zoom = 1; // fixme: should depend on height
that.map = self.map = new google.maps.Map(self.$map.$element[0], {
center: self.center,
disableDefaultUI: true,
disableDoubleClickZoom: true,
mapTypeId: google.maps.MapTypeId[getMapType()],
zoom: self.zoom
});
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.addListenerOnce(self.map, 'tilesloaded', tilesLoaded);
mapBounds && self.map.fitBounds(mapBounds);
/*
setTimeout(function() {
}, 1000);
*/
self.options.places.forEach(function(place, i) {
self.places[i] = new Ox.MapPlace(Ox.extend({
map: that
}, place))/*.add()*/;
});
google.maps.event.trigger(self.map, 'resize');
//that.gainFocus();
that.triggerEvent('load');
function tilesLoaded() { function tilesLoaded() {
// fixme: can add earlier, use don't replace map contents option // fixme: can add earlier, use don't replace map contents option
Ox.forEach(self.$navigationButtons, function(button) { Ox.forEach(self.$navigationButtons, function(button) {
@ -713,21 +739,57 @@ Ox.Map = function(options, self) {
var bounds; var bounds;
if (self.boundsChanged) { if (self.boundsChanged) {
bounds = self.map.getBounds(); bounds = self.map.getBounds();
self.places.sort(function(a, b) { if (!self.isAsync) {
var sort = { self.places.sort(function(a, b) {
a: a.selected ? Infinity : var sort = {
bounds.contains(a.center) ? a.area : -Infinity, a: a.selected ? Infinity :
b: b.selected ? Infinity : bounds.contains(a.center) ? a.area : -Infinity,
bounds.contains(b.center) ? b.area : -Infinity, b: b.selected ? Infinity :
}; bounds.contains(b.center) ? b.area : -Infinity,
return sort.b - sort.a; };
}).forEach(function(place, i) { return sort.b - sort.a;
if (i < self.options.markers && !place.visible) { }).forEach(function(place, i) {
place.add(); if (i < self.options.maxMarkers && !place.visible) {
} else if (i >= self.options.markers && place.visible) { place.add();
place.remove(); } else if (i >= self.options.maxMarkers && place.visible) {
} place.remove();
}); }
});
} else {
self.options.places({
area: {
south: bounds.getSouthWest().lat(),
west: bounds.getSouthWest().lng(),
north: bounds.getNorthEast().lat(),
east: bounds.getNorthEast().lng()
},
range: [0, self.options.maxMarkers],
sort: [{key: 'area', operator: '+'}],
}, function(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) {