Ext.ns('S100');
// Create the map and the markers. Each places layer will be managed by a cluster, to support turning
// on/off the pins.
S100.Map = function(mapId, latLng) {
this.mapId = mapId;
this.latLng = latLng;
this.layers = {};
this.baseLayers = [];
this.init();
this.setupEvents();
};
S100.Map.prototype.init = function() {
// this.setupStores();
this.createMap();
this.setupControls();
};
S100.Map.prototype.setupEvents = function() {
// Ext.fly(this.mapId).on('click', function() {
// console.log('clicked')
// }, this)
// Ext.fly(this.mapId).on('click', function() {
// this.closeInfoWindows();
// }, this)
};
S100.Map.prototype.setupStores = function() {
// console.log(this.baseLayers)
Ext.iterate(S100.Map.places, function(layerName, layer) {
// console.log(S100.Map.places[layer.name])
this[layerName+'Store'] = new Ext.data.JsonStore({
// store configs
// autoDestroy: true,
storeId: layerName+'Store',
proxy: {
type: 'memory',
data: S100.Map.places[layerName]
// reader: {
// type: 'json',
// root: layerName,
// idProperty: 'id'
// }
},
//alternatively, a Ext.data.Model name can be given (see Ext.data.Store for an example)
fields: ['name']
});
}, this);
};
S100.Map.prototype.createMap = function() {
var mapOptions = {
zoom: 11,
center: this.latLng,
// navigationControl: false,
navigationControlOptions: {
style: google.maps.NavigationControlStyle.SMALL
},
// scaleControl: true,
streetViewControl: true,
mapTypeControlOptions: {
mapTypeIds: [google.maps.MapTypeId.ROADMAP, google.maps.MapTypeId.TERRAIN, 's100map'],
position: google.maps.ControlPosition.RIGHT
// style: google.maps.MapTypeControlStyle.DROPDOWN_MENU
}
};
this.map = new google.maps.Map(Ext.fly(this.mapId).dom, mapOptions);
this.map.mapTypes.set('s100map', this.setupStyledMap("S100 Map"));
this.map.setMapTypeId('s100map');
// Make the info window close when clicking anywhere on the map.
google.maps.event.addListener(this.map, 'click', this.closeInfoWindows.createDelegate(this));
};
S100.Map.prototype.setupControls = function() {
this.layerControls = Ext.get(document.createElement('div'));
this.layerControls.addClass('s100-map-controls layer-controls');
this.map.controls[google.maps.ControlPosition.TOP_RIGHT].push(this.layerControls.dom);
this.filterControl = Ext.get(document.createElement('div'));
this.filterControl.addClass('s100-map-controls filter-controls');
this.map.controls[google.maps.ControlPosition.TOP_LEFT].push(this.filterControl.dom);
this.setupLegend();
this.setupKeyworkFilterNav();
};
S100.Map.prototype.setupKeyworkFilterNav = function() {
var tpl = new Ext.XTemplate(
''
);
this.filterControl.insertFirst({
id: 'keyword-filter',
cls: 'keyword-filter',
html: tpl.apply(S100.Map.keywords)
}).on('change', this.onKeywordFilterSelect, this);
};
S100.Map.prototype.onKeywordFilterSelect = function(evt, target) {
this.addFilterLayer('keyword', Ext.get(target).getValue(true));
};
S100.Map.prototype.setupLegend = function() {
this.legend = Ext.get(document.createElement('div'));
this.legend.set({'id': 's100-map-legend'});
var spec = {
tag: 'ol',
cn: [
{tag: 'li', cls: 's100-person', html: 'Seattle 100
Person'},
{tag: 'li', cls: 'c100-person', html: 'Community 100
Person'},
{tag: 'li', cls: 's100-place', html: 'Seattle 100
Place'},
{tag: 'li', cls: 'c100-place', html: 'Community 100
Place'}
]
};
this.legend.insertFirst({
id: 'map-legend',
el: 'div',
cn: spec
}).on('click', this.onLayerToggleNavClick, this);
this.map.controls[google.maps.ControlPosition.RIGHT].push(this.legend.dom);
};
// Add an initial layer to draw later
S100.Map.prototype.addBaseLayer = function(layerName, layerTitle) {
this.baseLayers.push({name: layerName, title: layerTitle});
};
// Draws all the initial layers
S100.Map.prototype.drawBaseLayers = function() {
// TODO check if the layers are already drawn
Ext.each(this.baseLayers, function(layer) {
this.setupLayer(layer.name, layer.title);
}, this);
};
// Sets up a new layer on the map stage
S100.Map.prototype.setupLayer = function(layerName, layerTitle, data, isFilterLayer) {
// If we already have this layer draw it back
if (this.getLayer(layerName)) {
var l = this.getLayer(layerName);
this.addLayerToggleNav(l);
l.draw();
return l;
}
var layer = new S100.MapLayer(this, layerName, layerTitle, data);
this.layers[layerName] = layer;
if (!isFilterLayer) {
this.addLayerToggleNav(layer);
}
return layer;
};
// Finds data by type and slug for a person or filters by keyword
S100.Map.prototype.addFilterLayer = function(type, key) {
// Assemble the data for the layer
var ids = [],
data,
layerName,
layerTitle,
filterLayer,
places = [],
people = [];
if ('person' == type) {
data = {};
Ext.each(S100.Map.places[type], function(item) {
if (key == item.slug) {
// Get the ids for the person's places
Ext.each(item.places, function(placeItem) {
ids.push(placeItem.id);
});
data = item;
// Get place items for found ids
Ext.each(S100.Map.places['place'], function(placeItem) {
if (ids.indexOf(placeItem.id) > -1) {
places.push(placeItem);
if (places.length == ids.length) return false; // Stop loop
}
});
// overwrite the places on item
data.places = places;
return false;
}
});
layerTitle = data.name;
layerName = data.slug;
} else if ('keyword' == type) {
var keywordName;
data = [];
Ext.iterate(S100.Map.places, function(modelName, model, placeModels) {
Ext.each(model, function(item) {
Ext.each(item.keywords, function(keyword) {
if (key == keyword.id) {
data.push(item);
keywordName = keyword.name;
}
});
});
});
if (keywordName) {
layerTitle = keywordName;
layerName = keywordName.urlize();
}
}
// Clear out all the layers and add a new filter layer
if (!Ext.isEmpty(data)) {
this.clearLayers();
filterLayer = this.setupLayer(layerName, layerTitle, data, true);
this.setFilter(filterLayer);
this.map.setCenter(this.latLng);
this.map.setZoom(12);
}
};
// Sets up a filter for the map, which clears all layers and layers toggle buttons.
// Should replace the toggle buttons with an indicator
// of what is being filtered (keywords, person, etc)
S100.Map.prototype.setFilter = function(filterLayer) {
this.removeFilterControlNav();
this.filterLayer = filterLayer;
this.activeFilter = filterLayer.getName();
this.filterControl.insertFirst({
el: 'div',
cls: 'active filter-name',
html: filterLayer.getTitle()
});
this.filterControl.insertFirst({
el: 'div',
cls: 'layer-control remove-filter',
html: 'Remove Filter'
}).on('click', this.onRemoveFilterClick, this);
};
S100.Map.prototype.onRemoveFilterClick = function() {
location.hash = '';
this.activeFilter = null;
this.filterControl.purgeAllListeners();
this.removeFilterControlNav();
this.setupKeyworkFilterNav();
this.clearLayer(this.filterLayer);
this.drawBaseLayers();
};
S100.Map.prototype.removeFilterControlNav = function(layer) {
if (!this.filterControl.first()) return;
var filterNavNodes = Ext.get(this.filterControl).select('.layer-control, .keyword-filter, .filter-name');
filterNavNodes.removeAllListeners();
filterNavNodes.remove();
};
S100.Map.prototype.hideLayer = function(layer) {
layer.clearLayer();
};
S100.Map.prototype.clearLayer = function(layer) {
this.removeLayerToggleNav(layer);
layer.clearLayer();
};
S100.Map.prototype.clearLayers = function() {
Ext.iterate(this.layers, function(layerName, layer) {
this.clearLayer(layer);
}, this);
};
S100.Map.prototype.setupStyledMap = function(mapName) {
var mapStyles = [
{
// featureType: "all",
// elementType: "all",
stylers: [
{ saturation: -100 }
]
}
];
// Give the new style a button name
var styledMapOptions = {
name: mapName
};
return new google.maps.StyledMapType(mapStyles, styledMapOptions);
};
S100.Map.prototype.addLayerToggleNav = function(layer) {
if (this.layerControls.child('#toggle-'+layer.getName())) return;
this.layerControls.insertFirst({
id: 'toggle-'+layer.getName(),
el: 'div',
"data-layer-name": layer.getName(),
cls: 'active toggle-layer toggle-'+layer.getName(),
html: layer.getTitle()
}).on('click', this.onLayerToggleNavClick, this);
};
S100.Map.prototype.removeLayerToggleNav = function(layer) {
var layerNav = Ext.get('toggle-'+layer.getName());
if (layerNav) {
// Ext.removeNode(layerNav);
layerNav.removeAllListeners();
layerNav.remove();
}
};
S100.Map.prototype.onLayerToggleNavClick = function(evt, target) {
target = Ext.get(target);
var layer = this.getLayer(Ext.get(target).getAttribute('data-layer-name'));
target.toggleClass('active');
if (target.hasClass('active')) {
this.setupLayer(layer.getName());
} else {
this.hideLayer(layer);
}
};
S100.Map.prototype.closeInfoWindows = function() {
Ext.iterate(this.layers, function(layerName, layer, obj) {
obj[layerName].closeInfoWindow();
});
};
S100.Map.prototype.getLayer = function(layerName) {
return this.layers[layerName];
};
S100.Map.prototype.getDomId = function() {
return this.mapId;
};