Home | Docs | Issue Tracker | FAQ | Download | |
Date: | 2012/10/08 |
---|---|
Author: | Thomas Bonfort |
Contact: | tbonfort@terriscope.fr |
Status: | Draft |
Version: | MapServer 6.4 |
MapServer has the ability to use multiple layers with MINSCALE/MAXSCALE filtering GROUP’d together when the need for scale-dependant datasources arises, e.g. like:
LAYER
NAME "roads_far"
GROUP "roads"
TYPE LINE
MINSCALE 100000
DATA "the_geom from roads_far"
CLASS
...
END
CLASS
...
END
END
LAYER
NAME "roads_close"
GROUP "roads"
TYPE LINE
MAXSCALE 100000
DATA "the_geom from roads_close"
CLASS
...
END
CLASS
...
END
END
While this solution works, it has the inconvenience of necessitating a duplication of the symbology throughout multiple layers, and may require some tweaking in order to hide the multiple layers in capabilities documents.
The current RFC proposes to mimic our current runtime-substitution mechanism to replace tokens inside a layer’s DATA statement. Instead of using an url parameter to accomplish the replacements, the token is replaced by a value that is dependant on the current map scale.
Examples are worth a thousand words here...
LAYER
..
SCALETOKEN
NAME "%priority%"
VALUES
"0" "1"
"1000" "2"
"10000" "3"
END
END
DATA "the_geom from mytable_%priority%" #data comes from a specific table
DATA "/path/to/roads_%priority%.shp" #data comes from a specific shapefile
DATA "the_geom_%priority% from roads" #data comes from a specific column in the table
DATA "the_geom_%priority% from (select * from roads where priority > %priority%) as foo" #data is filtered
CLASS
...
END
END
In the previous example, %priority% would be replaced by:
“1” for scales under 1,000 , giving:
DATA "the_geom from mytable_1"
DATA "/path/to/roads_1.shp"
DATA "the_geom_1 from roads"
DATA "the_geom_1 from (select * from roads where priority > 1) as foo"
“2” for scales between 1,000 and 10,000
DATA "the_geom from mytable_2"
DATA "/path/to/roads_2.shp"
DATA "the_geom_2 from roads"
DATA "the_geom_2 from (select * from roads where priority > 2) as foo"
“3” for scales over 10,000
DATA "the_geom from mytable_3"
DATA "/path/to/roads_3.shp"
DATA "the_geom_3 from roads"
DATA "the_geom_3 from (select * from roads where priority > 3) as foo"
LAYER
..
SCALETOKEN
NAME "%table%"
VALUES
"0" "roads"
"1000" "roads_gen_1"
"10000" "roads_gen_0"
END
END
DATA "the_geom from %table%" #data comes from a specific table
DATA "/path/to/%table%.shp" #data comes from a specific shapefile
CLASS
...
END
END
In the previous example, %table% would be replaced by:
“roads” for scales under 1,000 , giving:
DATA "the_geom from roads"
DATA "/path/to/roads.shp"
“roads_gen_1” for scales between 1,000 and 10,000
DATA "the_geom from roads_gen_1"
DATA "/path/to/roads_gen_1.shp"
“roads_gen_0” for scales over 10,000
DATA "the_geom from roads_gen_0"
DATA "/path/to/roads_gen_0.shp"
LAYER
..
SCALETOKEN
NAME "%filter%"
VALUES
"0" ""
"1000" "where type in ('motorway','trunk','primary')"
"10000" "where type='motorway'"
END
END
DATA "the_geom from (select * from roads %filter%) as foo"
CLASS
...
END
END
In the previous example, %filter% would be replaced by:
nothing for scales under 1,000 , giving:
DATA "the_geom from (select * from roads) as foo"
“where type in (‘motorway’,’trunk’,’primary’)” for scales between 1,000 and 10,000
DATA "the_geom from (select * from roads where type in ('motorway','trunk','primary')) as foo"
“where type=’motorway’” for scales over 10,000
DATA "the_geom from (select * from roads where type='motorway') as foo"
typedef struct {
double minscale;
double maxscale;
char* value;
} scaleTokenEntryObj;
typedef struct {
char* name;
char* default_value;
int n_entries;
scaleTokenEntryObj* tokens;
} scaleTokenObj;
struct layerObj {
...
scaleTokenObj* tokens;
int numscaletokens;
...
char* orig_data;
char* orig_tileindex;
char* orig_tileitem;
... etc ...
}
The following files will be modified/created by this RFC:
add getters/setters on layer scaletokens
This change provides a new functionality with no backwards compatibility issues being considered.
The tokens are defined in the mapfile and are not overridable by url, thus implying no more risk of sql injection or file system traversal than a classical DATA statement.
The token replacement is only done in msLayerOpen(), the performance impact should be negligeable as this happens only once per rendered layer.
None