Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added particular boundaries for the OTM Tiler #135

Open
wants to merge 7 commits into
base: develop
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .dockerignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
**/node_modules
**/build
**/public
26 changes: 26 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
FROM ubuntu:14.04

# set up our node install
RUN apt-get install -y software-properties-common && add-apt-repository -y ppa:ubuntu-toolchain-r/test

RUN apt-get update && apt-get install -y \
checkinstall \
g++ \
libstdc++-5-dev \
pkg-config \
libcairo2-dev \
libjpeg8-dev \
libgif-dev \
libpango1.0-dev \
curl

RUN curl -sL https://deb.nodesource.com/setup_6.x | sudo -E bash - && apt-get install -y --force-yes nodejs

RUN npm install -g yarn

WORKDIR /usr/local/tiler
COPY . .

RUN yarn --force

CMD node server.js
11 changes: 9 additions & 2 deletions config.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ var canopyBoundarySql = [

module.exports = {
"filterQueryArgumentName": "q",
"showTreeCondition": "showTreeCondition",
"displayQueryArgumentName": "show",
"restrictFeatureQueryArgumentName": "restrict",
// This is the column name of the hstore column used for scalar udfs
Expand All @@ -29,7 +30,7 @@ module.exports = {
"point": "the_geom_webmercator",
"polygon": "stormwater_polygonalmapfeature.polygon"
},
"base": "feature_type, treemap_tree.id AS tree_id",
"base": "feature_type, treemap_tree.id AS tree_id, <%= importerField %> as importer_id, <%= conditionField %> as condition",
"polygon": "feature_type",
"utfGrid": "feature_type, treemap_mapfeature.id AS id"
},
Expand Down Expand Up @@ -74,6 +75,10 @@ module.exports = {
"depends": ["mapFeature"],
"sql": "LEFT OUTER JOIN treemap_mapfeaturephoto ON treemap_mapfeature.id = treemap_mapfeaturephoto.map_feature_id"
},
"treeRowImport": {
"depends": ["mapFeature", "tree"],
"sql": "JOIN importer_treeimportrow on importer_treeimportrow.plot_id = treemap_tree.plot_id"
},
"udf": {
// Despite mapFeature not being referenced in the "sql" property it will
// be used in the filter for udf and so it is required
Expand All @@ -88,6 +93,7 @@ module.exports = {
},
"treeDisplayFilters": ["EmptyPlot", "Tree"],
"boundaryGrainstoreSql": "SELECT the_geom_webmercator FROM treemap_boundary JOIN treemap_instance_boundaries ON treemap_instance_boundaries.boundary_id = treemap_boundary.id WHERE treemap_instance_boundaries.instance_id=<%= instanceid %> AND treemap_boundary.searchable=true",
"boundaryLayerGrainstoreSql": "SELECT the_geom_webmercator, category, name FROM treemap_boundary WHERE treemap_boundary.category='<%= category %>' AND treemap_boundary.searchable=true",
"getBoundarySql" : "SELECT the_geom_webmercator FROM treemap_boundary WHERE id=<%= boundaryId %>",
"canopyBoundarySql": canopyBoundarySql,
"showAtZoomSql": "(treemap_mapfeature.hide_at_zoom IS NULL OR treemap_mapfeature.hide_at_zoom < <%= zoom %>)",
Expand All @@ -105,7 +111,8 @@ module.exports = {
"bioswale": "stormwater_bioswale",
"species": "treemap_species",
"mapFeaturePhoto": "treemap_mapfeaturephoto",
"udf": "treemap_userdefinedcollectionvalue"
"udf": "treemap_userdefinedcollectionvalue",
"treeRowImport": "importer_treeimportrow"
},
"udfcTemplates": {
"tree": "treemap_userdefinedcollectionvalue.field_definition_id=<%= fieldDefId %> AND treemap_userdefinedcollectionvalue.model_id=treemap_tree.id",
Expand Down
20 changes: 17 additions & 3 deletions makeSql.js
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,8 @@ var utils = require('./filterObjectUtils');
// Assumes that instanceid is an integer, ready to be plugged
// directly into SQL
function makeSqlForMapFeatures(filterString, displayString, restrictFeatureString, instanceid,
zoom, isUtfGridRequest, isPolygonRequest, instanceConfig) {
zoom, isUtfGridRequest, isPolygonRequest, instanceConfig,
showImportedTrees, showTreeCondition) {
var geom_spec = config.sqlForMapFeatures.fields.geom,
geom_field = isPolygonRequest ? geom_spec.polygon : geom_spec.point,
parsedFilterObject = filterString ? JSON.parse(filterString) : {},
Expand Down Expand Up @@ -85,7 +86,13 @@ function makeSqlForMapFeatures(filterString, displayString, restrictFeatureStrin
} else if (isPolygonRequest) {
otherFields = config.sqlForMapFeatures.fields.polygon;
} else {
otherFields = config.sqlForMapFeatures.fields.base;
// we only sometimes want different colors for imported trees
var importerField = showImportedTrees ? 'importer_treeimportrow.id' : 'null';
var conditionField = showTreeCondition ? 'treemap_tree.udfs -> \'Condition\'' : 'null';
otherFields = _.template(config.sqlForMapFeatures.fields.base)({
'importerField': importerField,
'conditionField': conditionField
});
}

geom_field = util.format("%s AS %s",
Expand Down Expand Up @@ -122,6 +129,12 @@ function makeSqlForBoundaries(instanceid) {
});
}

function makeSqlForBoundariesLayers(category) {
return _.template(config.boundaryLayerGrainstoreSql)({
category: category
});
}

function makeSqlForCanopyBoundaries(instanceid, canopy_min, canopy_max, category) {
return _.template(config.canopyBoundarySql)({
instanceid: instanceid,
Expand All @@ -134,5 +147,6 @@ function makeSqlForCanopyBoundaries(instanceid, canopy_min, canopy_max, category
exports = module.exports = {
makeSqlForMapFeatures: makeSqlForMapFeatures,
makeSqlForCanopyBoundaries: makeSqlForCanopyBoundaries,
makeSqlForBoundaries: makeSqlForBoundaries
makeSqlForBoundaries: makeSqlForBoundaries,
makeSqlForBoundariesLayers: makeSqlForBoundariesLayers
};
31 changes: 22 additions & 9 deletions server.js
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ var ws;

var styles = {
boundary: fs.readFileSync('style/boundary.mms', {encoding: 'utf-8'}),
boundaryCategory: fs.readFileSync('style/boundaryCategory.mms', {encoding: 'utf-8'}),
canopy: fs.readFileSync('style/canopy.mms', {encoding: 'utf-8'}),
mapFeature: fs.readFileSync('style/mapFeature.mms', {encoding: 'utf-8'}),
uncoloredMapFeature: fs.readFileSync('style/uncoloredMapFeature.mms', {encoding: 'utf-8'}),
Expand Down Expand Up @@ -97,26 +98,38 @@ var windshaftConfig = {
table = req.params.table;
zoom = req.params.z;
isPolygonRequest = (table === 'stormwater_polygonalmapfeature');
if (table === 'treemap_mapfeature' || isPolygonRequest) {
if (table === 'treemap_mapfeature' || isPolygonRequest || table === 'importer_treerowimport') {
filterString = req.query[config.filterQueryArgumentName];
displayString = req.query[config.displayQueryArgumentName];
restrictFeatureString = req.query[config.restrictFeatureQueryArgumentName];
isUtfGridRequest = (req.params.format === 'grid.json');
req.params.sql = makeSql.makeSqlForMapFeatures(filterString,
displayString,
restrictFeatureString,
instanceid,
zoom,
isUtfGridRequest,
isPolygonRequest,
req.instanceConfig);

var showImportedTrees = table === 'importer_treerowimport';
var showTreeCondition = req.query[config.showTreeCondition] === 'true';

req.params.sql = makeSql.makeSqlForMapFeatures(
filterString,
displayString,
restrictFeatureString,
instanceid,
zoom,
isUtfGridRequest,
isPolygonRequest,
req.instanceConfig,
showImportedTrees,
showTreeCondition
);
if (isPolygonRequest) {
req.params.style = styles.polygonalMapFeature;
} else if (isUtfGridRequest) {
req.params.style = styles.uncoloredMapFeature;
} else {
req.params.style = styles.mapFeature;
}
} else if (table === 'treemap_boundary' && 'category' in req.query) {
category = req.query.category;
req.params.sql = makeSql.makeSqlForBoundariesLayers(category);
req.params.style = styles.boundaryCategory;
} else if (table === 'treemap_boundary' && instanceid) {
req.params.sql = makeSql.makeSqlForBoundaries(instanceid);
req.params.style = styles.boundary;
Expand Down
80 changes: 80 additions & 0 deletions style/boundaryCategory.mms
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
#treemap_boundary {
::case {
line-width: 1;
line-color:#000;
line-opacity: 0.6;

[category="Neighborhood"] {
line-width: 5;
line-color:#ddd;
line-opacity: 0.7;
}
[category="Main Neighborhood"] {
line-width: 5;
line-color:#ddd;
line-opacity: 0.7;
}
[category="Ward"] {
line-width: 5;
line-color:#ddd;
line-opacity: 0.7;
}
}

::fill {
line-width: 0.75;
line-color: #000;
line-opacity: 0.8;
polygon-fill: #55A9F2;
polygon-opacity: 0.2;

[category="Parcels"] {
polygon-fill: #ED9FA7;
polygon-opacity: 0.2;
}

[category="Zones"] {
polygon-fill: #ED9FA7;
polygon-opacity: 0.2;
}

[category="SID"] {
polygon-fill: #ED9FA7;
polygon-opacity: 0.2;
}

[category="Park"] {
polygon-fill: #ED9FA7;
polygon-opacity: 0.2;
}

[category="Main Neighborhood"] {
polygon-fill: #55A9F2;
polygon-opacity: 0.2;
}

[category="Neighborhood"] {
polygon-fill: #557CF2;
polygon-opacity: 0.2;
}

[category="Ward"] {
polygon-fill: #55A9F2;
polygon-opacity: 0.2;
}
}

::label {
text-name: '[name]';
text-face-name: 'DejaVu Sans Bold';
text-fill: #000;
text-size: 12;
text-halo-fill: rgba(255, 255, 255, 0.5);
text-halo-radius: 1;
text-placement: interior;
text-avoid-edges: false;

[zoom < 14] { text-name: ''; }
[category="Parcels"] { text-name: ''; }
}
}
27 changes: 27 additions & 0 deletions style/mapFeature.mms
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,15 @@
@empty_plot_fill_color: #E1C6FF;
@empty_plot_stroke_color: #D4B5F9;

@imported_tree_fill_color: #85B4ED;
@imported_tree_stroke_color: #6E9AE0;

@tree_unhealthy_fill_color: #8B1002;
@tree_dead_fill_color: #303031;

@tree_unhealthy_stroke_color: #B5554A;
@tree_dead_stroke_color: #646469;

@gsi_fill_color: #388E8E;

@tree_gsi_border_color: #b6ce78;
Expand All @@ -18,6 +27,15 @@
[tree_id=null][feature_type="Plot"] {
marker-fill: @empty_plot_fill_color;
}
[tree_id!=null][feature_type="Plot"][importer_id!=null] {
marker-fill: @imported_tree_fill_color;
}
[tree_id!=null][feature_type="Plot"][condition="Dead"] {
marker-fill: @tree_dead_fill_color;
}
[tree_id!=null][feature_type="Plot"][condition="Unhealthy"] {
marker-fill: @tree_unhealthy_fill_color;
}

[feature_type!="Plot"] {
marker-fill: @gsi_fill_color;
Expand All @@ -34,6 +52,15 @@
[tree_id!=null][feature_type="Plot"][zoom >= 15] {
marker-line-color: @tree_gsi_border_color;
}
[tree_id!=null][feature_type="Plot"][zoom >= 15][importer_id!=null] {
marker-line-color: @imported_tree_stroke_color;
}
[tree_id!=null][feature_type="Plot"][zoom >= 15][condition="Dead"] {
marker-line-color: @tree_dead_stroke_color;
}
[tree_id!=null][feature_type="Plot"][zoom >= 15][condition="Unhealthy"] {
marker-line-color: @tree_unhealthy_stroke_color;
}
[feature_type!="Plot"][zoom >= 15] {
marker-line-color: @tree_gsi_border_color;
}
Expand Down