Skip to content

Commit

Permalink
expand esri map viewer
Browse files Browse the repository at this point in the history
  • Loading branch information
eliotjordan committed Jan 8, 2016
1 parent 96138f7 commit fac7de3
Show file tree
Hide file tree
Showing 28 changed files with 506 additions and 82 deletions.
1 change: 0 additions & 1 deletion Rakefile
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ BLACKLIGHT_JETTY_VERSION = '4.10.3'
ZIP_URL = "https://github.com/projectblacklight/blacklight-jetty/archive/v#{BLACKLIGHT_JETTY_VERSION}.zip"
APP_ROOT = File.dirname(__FILE__)


require 'rspec/core/rake_task'
require 'engine_cart/rake_task'
require 'jettywrapper'
Expand Down
1 change: 0 additions & 1 deletion app/assets/javascripts/geoblacklight/modules/item.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ Blacklight.onLoad(function() {
// get viewer module from protocol value and capitalize to match class name
var viewerName = $(element).data().protocol,
viewer;
viewerName = viewerName.charAt(0).toUpperCase() + viewerName.substring(1);

// get new viewer instance and pass in element
viewer = new window['GeoBlacklight']['Viewer'][viewerName](element);
Expand Down
86 changes: 86 additions & 0 deletions app/assets/javascripts/geoblacklight/viewers/esri.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
//= require geoblacklight/viewers/map

GeoBlacklight.Viewer.Esri = GeoBlacklight.Viewer.Map.extend({
layerInfo: {},

layerOptions: {

// sets initial layer opacity
opacity: 0.75
},

load: function() {
this.options.bbox = L.bboxToBounds(this.data.mapBbox);
this.map = L.map(this.element).fitBounds(this.options.bbox);
this.map.addLayer(this.selectBasemap());
this.map.addLayer(this.overlay);
if (this.data.available) {
this.getEsriLayer();
} else {
this.addBoundsOverlay(this.options.bbox);
}
},

getEsriLayer: function() {
var _this = this;

// remove any trailing slash from endpoint url
_this.data.url = _this.data.url.replace(/\/$/, '');

L.esri.get = L.esri.Request.get.JSONP;
L.esri.get(_this.data.url, {}, function(error, response){
if(!error) {
_this.layerInfo = response;

// get layer as defined in submodules (e.g. esri/mapservice)
var layer = _this.getPreviewLayer();

// add layer to map
if (_this.addPreviewLayer(layer)) {

// add control if layer is added
_this.addOpacityControl();
}
}
});
},

addPreviewLayer: function(layer) {

// if not null, add layer to map
if (layer) {

this.overlay.addLayer(layer);
return true;
}
},

// clear attribute table and setup spinner icon
appendLoadingMessage: function() {
var spinner = '<tbody class="attribute-table-body"><tr><td colspan="2">' +
'<span id="attribute-table">' +
'<i class="fa fa-spinner fa-spin fa-align-center">' +
'</i></span>' +
'</td></tr></tbody>';

$('.attribute-table-body').html(spinner);
},

// appends error message to attribute table
appendErrorMessage: function() {
$('.attribute-table-body').html('<tbody class="attribute-table-body">'+
'<tr><td colspan="2">Could not find that feature</td></tr></tbody>');
},

// populates attribute table with feature properties
populateAttributeTable: function(feature) {
var html = $('<tbody class="attribute-table-body"></tbody>');

// step through properties and append to table
for (var property in feature.properties) {
html.append('<tr><td>' + property + '</td>'+
'<td>' + feature.properties[property] + '</tr>');
}
$('.attribute-table-body').replaceWith(html);
}
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
//= require geoblacklight/viewers/esri

GeoBlacklight.Viewer.DynamicMapLayer = GeoBlacklight.Viewer.Esri.extend({

// override to parse between dynamic layer types
getEsriLayer: function() {
var _this = this;

// remove any trailing slash from endpoint url
_this.data.url = _this.data.url.replace(/\/$/, '');

// get last segment from url
var pathArray = this.data.url.replace(/\/$/, '').split('/');
var lastSegment = pathArray[pathArray.length - 1];

// if the last seg is an integer, slice and save as dynamicLayerId
if (Number(lastSegment) === parseInt(lastSegment, 10)) {
this.dynamicLayerId = lastSegment;
this.data.url = this.data.url.slice(0,-(lastSegment.length + 1));
}

L.esri.get = L.esri.Request.get.JSONP;
L.esri.get(_this.data.url, {}, function(error, response){
if(!error) {
_this.layerInfo = response;

// get layer
var layer = _this.getPreviewLayer();

// add layer to map
if (_this.addPreviewLayer(layer)) {

// add control if layer is added
_this.addOpacityControl();
}
}
});
},

getPreviewLayer: function() {

// set layer url
this.layerOptions.url = this.data.url;

// show only single layer, if specified
if (this.dynamicLayerId) {
this.layerOptions.layers = [this.dynamicLayerId];
}

var esriDynamicMapLayer = L.esri.dynamicMapLayer(this.layerOptions);

// setup feature inspection
this.setupInspection(esriDynamicMapLayer);
return esriDynamicMapLayer;
},

setupInspection: function(layer) {
var _this = this;
this.map.on('click', function(e) {
_this.appendLoadingMessage();

// query layer at click location
var identify = L.esri.Tasks.identifyFeatures({
url: layer.options.url,
useCors: true
})
.tolerance(0)
.returnGeometry(false)
.on(_this.map)
.at(e.latlng);

// query specific layer if dynamicLayerId is set
if (_this.dynamicLayerId) {
identify.layers('ID: ' + _this.dynamicLayerId);
}

identify.run(function(error, featureCollection, response){
if (error) {
_this.appendErrorMessage();
} else {
_this.populateAttributeTable(featureCollection.features[0]);
}
});
});
}
});
78 changes: 78 additions & 0 deletions app/assets/javascripts/geoblacklight/viewers/esri/feature_layer.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
//= require geoblacklight/viewers/esri

GeoBlacklight.Viewer.FeatureLayer = GeoBlacklight.Viewer.Esri.extend({

// default feature styles
defaultStyles: {
'esriGeometryPoint': '',
'esriGeometryMultipoint': '',
'esriGeometryPolyline': {color: 'blue', weight: 3 },
'esriGeometryPolygon': {color: 'blue', weight: 2 }
},

getPreviewLayer: function() {

// set layer url
this.layerOptions.url = this.data.url;

// set default style
this.layerOptions.style = this.getFeatureStyle();

// define feature layer
this.esriFeatureLayer = L.esri.featureLayer(this.layerOptions);

//setup feature inspection and opacity
this.setupInspection(this.esriFeatureLayer);
this.setupInitialOpacity(this.esriFeatureLayer);

return this.esriFeatureLayer;
},

// override opacity control because feature layer is special
addOpacityControl: function() {

// define setOpacity function that works for svg elements
this.esriFeatureLayer.setOpacity = function(opacity) {
$('.leaflet-clickable').css({ opacity: opacity });
};

// add new opacity control
this.map.addControl(new L.Control.LayerOpacity(this.esriFeatureLayer));
},

getFeatureStyle: function() {
var _this = this;

// lookup style hash based on layer geometry type and return function
return function(feature) {
return _this.defaultStyles[_this.layerInfo.geometryType];
};
},

setupInitialOpacity: function(featureLayer) {
featureLayer.on('load', function(e) {
featureLayer.setOpacity(0.75);
});
},

setupInspection: function(featureLayer) {
var _this = this;

// inspect on click
featureLayer.on('click', function(e) {
_this.appendLoadingMessage();

// query layer at click location
featureLayer.query()
.returnGeometry(false)
.intersects(e.latlng)
.run(function(error, featureCollection, response){
if (error) {
_this.appendErrorMessage();
} else {
_this.populateAttributeTable(featureCollection.features[0]);
}
});
});
}
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
//= require geoblacklight/viewers/esri

GeoBlacklight.Viewer.ImageMapLayer = GeoBlacklight.Viewer.Esri.extend({
layerInfo: {},

getPreviewLayer: function() {

// set layer url
this.layerOptions.url = this.data.url;

// return image service layer
return L.esri.imageMapLayer(this.layerOptions);
}
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
//= require geoblacklight/viewers/esri

GeoBlacklight.Viewer.TiledMapLayer = GeoBlacklight.Viewer.Esri.extend({

getPreviewLayer: function() {

// set layer url
this.layerOptions.url = this.data.url;

// check if this is a tile map and layer and for correct spatial reference
if (this.layerInfo.singleFusedMapCache === true && this.layerInfo.spatialReference.wkid === 102100) {

/**
* TODO: allow non-mercator projections and custom scales
* - use Proj4Leaflet
*/

//
var esriTiledMapLayer = L.esri.tiledMapLayer(this.layerOptions);

//setup feature inspection
this.setupInspection(esriTiledMapLayer);

return esriTiledMapLayer;
}
},

setupInspection: function(layer) {
var _this = this;
this.map.on('click', function(e) {
_this.appendLoadingMessage();

// query layer at click location
L.esri.Tasks.identifyFeatures({
url: layer.options.url,
useCors: true
})
.tolerance(0)
.returnGeometry(false)
.on(_this.map)
.at(e.latlng)
.run(function(error, featureCollection, response) {
if (error) {
_this.appendErrorMessage();
} else {
_this.populateAttributeTable(featureCollection.features[0]);
}
});
});
}
});
Loading

0 comments on commit fac7de3

Please sign in to comment.