Skip to content

Commit

Permalink
Extended recline map view in order to customize base map layer.
Browse files Browse the repository at this point in the history
  • Loading branch information
Khalegh-H3 authored and jrods committed Aug 12, 2016
1 parent 5694d09 commit ce4c989
Show file tree
Hide file tree
Showing 5 changed files with 117 additions and 6 deletions.
15 changes: 15 additions & 0 deletions ckanext/reclineview/plugin.py
Expand Up @@ -5,12 +5,20 @@
from ckan.common import json
import ckan.plugins as p
import ckan.plugins.toolkit as toolkit
from pylons import config

log = getLogger(__name__)
ignore_empty = p.toolkit.get_validator('ignore_empty')
natural_number_validator = p.toolkit.get_validator('natural_number_validator')
Invalid = p.toolkit.Invalid

def get_mapview_config():
'''
Extracts and returns map view configuration of the reclineview extension.
'''
namespace = 'ckanext.reclineview.mapview.'
return dict([(k.replace(namespace, ''), v) for k, v in config.iteritems()
if k.startswith(namespace)])

def in_list(list_possible_values):
'''
Expand Down Expand Up @@ -174,6 +182,8 @@ class ReclineMapView(ReclineViewBase):
This extension views resources using a Recline map.
'''

p.implements(p.ITemplateHelpers, inherit=True)

map_field_types = [{'value': 'lat_long',
'text': 'Latitude / Longitude fields'},
{'value': 'geojson', 'text': 'GeoJSON'}]
Expand Down Expand Up @@ -234,3 +244,8 @@ def setup_template_variables(self, context, data_dict):

def form_template(self, context, data_dict):
return 'recline_map_form.html'

def get_helpers(self):
return {
'get_mapview_config': get_mapview_config
}
89 changes: 89 additions & 0 deletions ckanext/reclineview/theme/public/mapview_ext.js
@@ -0,0 +1,89 @@
/**
* Author: Khalegh Mamakani @ Highway Three Solutions Inc.
*
* Copyright 2016 Province of British Columbia
**/
(function (ckan, jQuery) {

ckan.MapView = recline.View.Map.extend({

initialize : function (options) {
this.mapConfig = options.mapConfig;
recline.View.Map.prototype.initialize.apply(this, [options])
},

_setupMap: function(){

var self = this;

var mapConfig = this.mapConfig;
/*
If no map configuration is provided use recline default map tiles.
*/
if ((typeof mapConfig === 'undefined') || jQuery.isEmptyObject(mapConfig)) {
recline.View.Map.prototype._setupMap.apply(this);
return;
}

var isHttps = window.location.href.substring(0, 5).toLowerCase() === 'https';

var leafletMapOptions = this.leafletMapOptions || {};
var leafletBaseLayerOptions = jQuery.extend(this.leafletBaseLayerOptions, {
maxZoom: 18
});

this.map = new L.Map(this.$map.get(0));

var baseLayerUrl = '';

if (mapConfig.type == 'mapbox') {
// MapBox base map
if (!mapConfig['mapbox.map_id'] || !mapConfig['mapbox.access_token']) {
throw '[CKAN Map Widgets] You need to provide a map ID ([account].[handle]) and an access token when using a MapBox layer. ' +
'See http://www.mapbox.com/developers/api-overview/ for details';
}

baseLayerUrl = '//{s}.tiles.mapbox.com/v4/' + mapConfig['mapbox.map_id'] + '/{z}/{x}/{y}.png?access_token=' + mapConfig['mapbox.access_token'];
leafletBaseLayerOptions.handle = mapConfig['mapbox.map_id'];
leafletBaseLayerOptions.subdomains = mapConfig.subdomains || 'abcd';
leafletBaseLayerOptions.attribution = mapConfig.attribution || 'Data: <a href="http://osm.org/copyright" target="_blank">OpenStreetMap</a>, Design: <a href="http://mapbox.com/about/maps" target="_blank">MapBox</a>';
} else if (mapConfig.type == 'custom') {
// Custom XYZ layer
baseLayerUrl = mapConfig['custom.url'];
if (mapConfig.subdomains) leafletBaseLayerOptions.subdomains = mapConfig.subdomains;
if (mapConfig.tms) leafletBaseLayerOptions.tms = mapConfig.tms;
leafletBaseLayerOptions.attribution = mapConfig.attribution;
} else {

// MapQuest OpenStreetMap base map
if (isHttps) {
baseLayerUrl = '//otile{s}-s.mqcdn.com/tiles/1.0.0/osm/{z}/{x}/{y}.png';
} else {
baseLayerUrl = '//otile{s}.mqcdn.com/tiles/1.0.0/osm/{z}/{x}/{y}.png';
}
leafletBaseLayerOptions.subdomains = mapConfig.subdomains || '1234';
leafletBaseLayerOptions.attribution = mapConfig.attribution || 'Map data &copy; OpenStreetMap contributors, Tiles Courtesy of <a href="http://www.mapquest.com/" target="_blank">MapQuest</a> <img src="//developer.mapquest.com/content/osm/mq_logo.png">';
}

var baseLayer = new L.TileLayer(baseLayerUrl, leafletBaseLayerOptions);
this.map.addLayer(baseLayer);

this.markers = new L.MarkerClusterGroup(this._clusterOptions);

// rebind this (as needed in e.g. default case above)
this.geoJsonLayerOptions.pointToLayer = _.bind(
this.geoJsonLayerOptions.pointToLayer,
this);
this.features = new L.GeoJSON(null, this.geoJsonLayerOptions);

var ckanext_reclineview_map_center = JSON.parse(mapConfig.center || '[0, 0]');
var ckanext_reclineview_map_zoom = parseInt(mapConfig.zoom || '2');

this.map.setView(ckanext_reclineview_map_center, ckanext_reclineview_map_zoom);

this.mapReady = true;
}

});

})(this.ckan, this.jQuery);
15 changes: 9 additions & 6 deletions ckanext/reclineview/theme/public/recline_view.js
Expand Up @@ -46,7 +46,7 @@ this.ckan.module('recline_view', function (jQuery, _) {
}
}

var errorMsg, dataset;
var errorMsg, dataset, map_config;

if (!resourceData.datastore_active) {
recline.Backend.DataProxy.timeout = 10000;
Expand All @@ -58,6 +58,8 @@ this.ckan.module('recline_view', function (jQuery, _) {

dataset = new recline.Model.Dataset(resourceData);

map_config = this.options.map_config;

var query = new recline.Model.Query();
query.set({ size: reclineView.limit || 100 });
query.set({ from: reclineView.offset || 0 });
Expand Down Expand Up @@ -119,9 +121,9 @@ this.ckan.module('recline_view', function (jQuery, _) {
state.lonField = reclineView.longitude_field;
}

view = new recline.View.Map({model: dataset, state: state});
view = new ckan.MapView({model: dataset, state: state, mapConfig: map_config});
} else if(reclineView.view_type === "recline_view") {
view = this._newDataExplorer(dataset);
view = this._newDataExplorer(dataset, this.options.map_config);
} else {
// default to Grid
view = new recline.View.SlickGrid({model: dataset});
Expand All @@ -148,7 +150,7 @@ this.ckan.module('recline_view', function (jQuery, _) {
}
},

_newDataExplorer: function (dataset) {
_newDataExplorer: function (dataset, map_config) {
var views = [
{
id: 'grid',
Expand All @@ -167,8 +169,9 @@ this.ckan.module('recline_view', function (jQuery, _) {
{
id: 'map',
label: 'Map',
view: new recline.View.Map({
model: dataset
view: new ckan.MapView({
model: dataset,
mapConfig: map_config
})
}
];
Expand Down
2 changes: 2 additions & 0 deletions ckanext/reclineview/theme/public/resource.config
Expand Up @@ -38,6 +38,8 @@ main =

vendor/recline/recline.js

mapview_ext.js

widget.recordcount.js
recline_view.js

Expand Down
2 changes: 2 additions & 0 deletions ckanext/reclineview/theme/templates/recline_view.html
Expand Up @@ -2,10 +2,12 @@

{% block page %}

{% set map_config = h.get_mapview_config() %}
<div data-module="recline_view"
data-module-site_url="{{ h.dump_json(h.url('/', locale='default', qualified=true)) }}"
data-module-resource = "{{ h.dump_json(resource_json) }}";
data-module-resource-view = "{{ h.dump_json(resource_view_json) }}";
data-module-map_config= "{{ h.dump_json(map_config) }}";
>
<h4 class="loading-dialog">
<div class="loading-spinner"></div>
Expand Down

0 comments on commit ce4c989

Please sign in to comment.