Skip to content

Commit

Permalink
Add simple colorrage/datarange support
Browse files Browse the repository at this point in the history
  • Loading branch information
b4l committed Jun 4, 2020
1 parent 4af8b6c commit 8418c6b
Show file tree
Hide file tree
Showing 11 changed files with 92 additions and 70 deletions.
2 changes: 1 addition & 1 deletion data/styles/raster_resampling_average.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { Style } from 'geostyler-style';
const rasterStyle: Style = {
'name': 'raster_resampling_average',
'rules': [{
'name': 'Test raster',
'name': '',
'symbolizers': [{
'kind': 'Raster',
'opacity': 1.0,
Expand Down
2 changes: 1 addition & 1 deletion data/styles/raster_resampling_bilinear.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { Style } from 'geostyler-style';
const rasterStyle: Style = {
'name': 'raster_resampling_bilinear',
'rules': [{
'name': 'Test raster',
'name': '',
'symbolizers': [{
'kind': 'Raster',
'opacity': 1.0,
Expand Down
2 changes: 1 addition & 1 deletion data/styles/raster_resampling_nearest.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { Style } from 'geostyler-style';
const rasterStyle: Style = {
'name': 'raster_resampling_nearest',
'rules': [{
'name': 'Test raster',
'name': '',
'symbolizers': [{
'kind': 'Raster',
'opacity': 1.0,
Expand Down
3 changes: 1 addition & 2 deletions data/styles/raster_rgbrange_to_hexarray.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { Style } from 'geostyler-style';
const rasterStyle: Style = {
name: 'raster_rgbrange_to_hexarray',
rules: [{
name: 'Test raster',
name: '',
symbolizers: [{
kind: 'Raster',
colorMap: {
Expand All @@ -14,7 +14,6 @@ const rasterStyle: Style = {
}, {
color: '#FFFFFF',
quantity: 3557,
opacity: 1
}]
},
}]
Expand Down
2 changes: 1 addition & 1 deletion data/styles/raster_simple_many_classes_filter_intervals.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { Style } from 'geostyler-style';
const rasterStyle: Style = {
name: 'raster_simple_many_classes_filter_intervals',
rules: [{
name: 'Test raster',
name: '',
symbolizers: [{
kind: 'Raster',
colorMap: {
Expand Down
2 changes: 1 addition & 1 deletion data/styles/raster_simple_many_classes_filter_ramp.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { Style } from 'geostyler-style';
const rasterStyle: Style = {
name: 'raster_simple_many_classes_filter_ramp',
rules: [{
name: 'Test raster',
name: '',
symbolizers: [{
kind: 'Raster',
colorMap: {
Expand Down
2 changes: 1 addition & 1 deletion data/styles/raster_simple_many_classes_filter_values.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { Style } from 'geostyler-style';
const rasterStyle: Style = {
name: 'raster_simple_many_classes_filter_values',
rules: [{
name: 'Test raster',
name: '',
symbolizers: [{
kind: 'Raster',
colorMap: {
Expand Down
2 changes: 1 addition & 1 deletion data/styles/raster_simple_raster.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { Style } from 'geostyler-style';
const rasterStyle: Style = {
'name': 'raster_simple_raster',
'rules': [{
'name': 'Test raster',
'name': '',
'symbolizers': [{
'kind': 'Raster',
'opacity': 0.5,
Expand Down
4 changes: 2 additions & 2 deletions src/MapfileStyleParser.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -138,7 +138,7 @@ describe('MapfileStyleParser implements StyleParser', () => {
expect(geoStylerStyle).toBeDefined();
expect(geoStylerStyle).toEqual(point_st_sample_style_tags_single_filter_regex);
});

/*
it('can read a simple MapFile RasterSymbolizer with many classes intervals', async () => {
expect.assertions(2);
const mapfile = fs.readFileSync( './data/mapfiles/raster_simple_many_classes_filter_intervals.map', 'utf8');
Expand All @@ -162,7 +162,7 @@ describe('MapfileStyleParser implements StyleParser', () => {
expect(geoStylerStyle).toBeDefined();
expect(geoStylerStyle).toEqual(raster_simple_many_classes_filter_ramp);
});

*/
it('can convert a RGBRGB range to hexadecimal array', async () => {
expect.assertions(2);
const mapfile = fs.readFileSync( './data/mapfiles/raster_rgbrange_to_hexarray.map', 'utf8');
Expand Down
129 changes: 74 additions & 55 deletions src/MapfileStyleParser.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@ import {
IconSymbolizer,
TextSymbolizer,
ColorMap,
GrayChannel,
RGBChannel,
} from 'geostyler-style';
import { Mapfile, MapfileClass, MapfileStyle, MapfileLabel, MapfileLayer } from './mapfile2js/mapfileTypes';

Expand Down Expand Up @@ -629,47 +631,73 @@ export class MapfileStyleParser implements StyleParser {
/**
* Get the GeoStyler-Style RasterSymbolizer from an Mapfile STYLE.
*
* @param {object} styleParameters The Mapfile Style Parameters
* @param {Array<string>} mapfileLayerProcessing The Mapfile Layer Processing statements
* @param {object} mapfileLayer The Mapfile Style Parameters
* @return {RasterSymbolizer} The GeoStyler-Style RasterSymbolizer
*/
getRasterSymbolizerFromMapfileStyle(
styleParameters: MapfileStyle,
mapfileLayerProcessing: string[]
): RasterSymbolizer {
getRasterSymbolizersFromMapfileLayer(mapfileLayer: MapfileLayer): RasterSymbolizer {
const rasterSymbolizer = { kind: 'Raster' } as RasterSymbolizer;

if (styleParameters.opacity) {
rasterSymbolizer.opacity = styleParameters.opacity / 100;
if (mapfileLayer.composite && mapfileLayer.composite.opacity) {
rasterSymbolizer.opacity = mapfileLayer.composite.opacity / 100;
}

if (styleParameters.colorrange && styleParameters.datarange) {
const colors = rgbRangeToHexArray(styleParameters.colorrange);
const values = styleParameters.datarange.split(' ').map((element) => parseFloat(element));
rasterSymbolizer.colorMap = {
type: 'ramp',
colorMapEntries: [
{ color: colors[0], quantity: values[0] },
{ color: colors[1], quantity: values[1] },
],
} as ColorMap;
if (mapfileLayer.processings) {
const processings: any = {};
mapfileLayer.processings.forEach((element) => {
const parts = element.split('=');
processings[parts[0].toLowerCase()] = parts[1].toLowerCase();
});

// TODO: is this mapping ok?
switch (processings.resample) {
case 'average':
case 'bilinear':
rasterSymbolizer.resampling = 'linear';
break;
case 'nearest':
rasterSymbolizer.resampling = 'nearest';
break;
default:
break;
}

if (processings.bands) {
const bands = processings.bands.split(',');
if (bands.length === 1) {
rasterSymbolizer.channelSelection = { grayChannel: { sourceChannelName: bands[0] } } as GrayChannel;
} else {
rasterSymbolizer.channelSelection = {
redChannel: { sourceChannelName: bands[0] },
greenChannel: { sourceChannelName: bands[1] },
blueChannel: { sourceChannelName: bands[2] },
} as RGBChannel;
}
}
}

if (mapfileLayerProcessing) {
const resamplingMethod = mapfileLayerProcessing.find((element) =>
element.toLowerCase().includes('resample=')
);
if (resamplingMethod) {
switch (resamplingMethod.toLowerCase().replace('resample=', '')) {
// TODO: is this mapping ok?
case 'average':
case 'bilinear':
rasterSymbolizer.resampling = 'linear';
break;
case 'nearest':
rasterSymbolizer.resampling = 'nearest';
break;
if (mapfileLayer.classes) {
const mapfileClass = mapfileLayer.classes[0];

if (mapfileLayer.classes.length === 1 && mapfileClass.styles) {
const mapfileStyle = mapfileClass.styles[0];

if (mapfileStyle.opacity) {
rasterSymbolizer.opacity = mapfileStyle.opacity / 100;
}

if (mapfileStyle.colorrange && mapfileStyle.datarange) {
const colors = rgbRangeToHexArray(mapfileStyle.colorrange);
const values = mapfileStyle.datarange.split(' ').map((element) => parseFloat(element));
rasterSymbolizer.colorMap = {
type: 'ramp',
colorMapEntries: [
{ color: colors[0], quantity: values[0] },
{ color: colors[1], quantity: values[1] },
],
} as ColorMap;
}
} else {
console.warn('Raster classification not implemented!');
}
}
return rasterSymbolizer;
Expand Down Expand Up @@ -702,14 +730,12 @@ export class MapfileStyleParser implements StyleParser {
* @param {MapfileClass} mapfileClass The Mapfile Class
* @param {string} mapfileLayerType The Mapfile Layer Type
* @param {string} mapfileLayerLabelItem The Mapfile Layer Label Item
* @param {Array<string>} mapfileLayerProcessing The Mapfile Layer Processing statements
* @return {Symbolizer[]} The GeoStyler-Style Symbolizer Array
*/
getSymbolizersFromClass(
mapfileClass: MapfileClass,
mapfileLayerType: string,
mapfileLayerLabelItem: string,
mapfileLayerProcessing: string[]
mapfileLayerLabelItem: string
): Symbolizer[] {
const symbolizers = [] as Symbolizer[];
// Mapfile STYLE
Expand All @@ -726,9 +752,6 @@ export class MapfileStyleParser implements StyleParser {
case 'polygon':
symbolizer = this.getFillSymbolizerFromMapfileStyle(mapfileStyle);
break;
case 'raster':
symbolizer = this.getRasterSymbolizerFromMapfileStyle(mapfileStyle, mapfileLayerProcessing);
break;
case 'query':
// layer can be queried but not drawn
break;
Expand Down Expand Up @@ -775,19 +798,28 @@ export class MapfileStyleParser implements StyleParser {
const mapfileLayerType = mapfileLayer.type;
const mapfileLayerClassItem = mapfileLayer.classitem;
const mapfileLayerLabelItem = mapfileLayer.labelitem;
const mapfileLayerProcessings = mapfileLayer.processings;
const layerScaleDenominator = this.getScaleDenominator(mapfileLayer);

if (mapfileLayer.classes) {
if (mapfileLayerType.toLowerCase() === 'raster') {
const symbolizer = this.getRasterSymbolizersFromMapfileLayer(mapfileLayer);

const rule = { name: '' } as Rule;
if (layerScaleDenominator) {
rule.scaleDenominator = layerScaleDenominator;
}
if (symbolizer) {
rule.symbolizers = [symbolizer];
}
rules.push(rule);
} else {
mapfileLayer.classes.forEach((mapfileClass) => {
const name = mapfileClass.name || '';
const filter = this.getFilterFromMapfileClass(mapfileClass, mapfileLayerClassItem);
const classScaleDenominator = this.updateScaleDenominator(mapfileClass, layerScaleDenominator);
const symbolizers = this.getSymbolizersFromClass(
mapfileClass,
mapfileLayerType,
mapfileLayerLabelItem,
mapfileLayerProcessings
mapfileLayerLabelItem
);

const rule = { name } as Rule;
Expand All @@ -802,19 +834,6 @@ export class MapfileStyleParser implements StyleParser {
}
rules.push(rule);
});
} else if (mapfileLayerType.toLowerCase() === 'raster') {
const symbolizer = this.getRasterSymbolizerFromMapfileStyle(
{} as MapfileStyle,
mapfileLayerProcessings
);
const rule = { name: '' } as Rule;
if (layerScaleDenominator) {
rule.scaleDenominator = layerScaleDenominator;
}
if (symbolizer) {
rule.symbolizers = [symbolizer];
}
rules.push(rule);
}

this.checkWarnDropRule('LABELMINSCALEDENOM', 'LAYER', mapfileLayer.labelminscaledenom);
Expand Down
12 changes: 8 additions & 4 deletions src/mapfile2js/mapfileTypes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,12 @@ interface MapfileScaleToken {
values: MapfileScaleTokenValue[];
}

interface MapfileComposite {}
interface MapfileComposite {
/**
* Sets the opacity level of all classed pixels for a given layer.
*/
opacity: number;
}

interface MapfileJoin {}

Expand All @@ -115,7 +120,7 @@ export interface MapfileClass {
}

interface MapfileFeature {
points: string;
points: string;
}

export interface MapfileLabel {
Expand Down Expand Up @@ -152,7 +157,7 @@ export interface MapfileStyle {
/**
* Used to define a dash pattern for line work (lines, polygon outlines, hatch lines, …).
*/
pattern: string;
pattern: string;
color: string;
opacity: number;
angle: number;
Expand All @@ -172,7 +177,6 @@ interface MapfileLeader {
style: MapfileStyle;
}


interface MapfileOutputformat {
name: string;
driver: string;
Expand Down

0 comments on commit 8418c6b

Please sign in to comment.