Merge branch 'master' of https://github.com/openlayers/openlayers into vendor-prefixes
This commit is contained in:
@@ -163,13 +163,13 @@ var map;
|
||||
var doc = request.responseText,
|
||||
caps = format.read(doc);
|
||||
fmzk = format.createLayer(caps, OpenLayers.Util.applyDefaults(
|
||||
{layer:"fmzk", requestEncoding:"REST", transitionEffect:"resize"}, defaults
|
||||
{layer:"fmzk", transitionEffect:"resize"}, defaults
|
||||
));
|
||||
aerial = format.createLayer(caps, OpenLayers.Util.applyDefaults(
|
||||
{layer:"lb", requestEncoding:"REST", transitionEffect:"resize"}, defaults
|
||||
{layer:"lb", transitionEffect:"resize"}, defaults
|
||||
));
|
||||
labels = format.createLayer(caps, OpenLayers.Util.applyDefaults(
|
||||
{layer:"beschriftung", requestEncoding:"REST", className:"nofade", isBaseLayer: false},
|
||||
{layer:"beschriftung", className:"nofade", isBaseLayer: false},
|
||||
defaults
|
||||
));
|
||||
map.addLayers([fmzk, aerial, labels]);
|
||||
|
||||
32
examples/osm-marker-popup.html
Normal file
32
examples/osm-marker-popup.html
Normal file
@@ -0,0 +1,32 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0">
|
||||
<meta name="apple-mobile-web-app-capable" content="yes">
|
||||
<title>OpenLayers OSM and Google Example</title>
|
||||
<link rel="stylesheet" href="../theme/default/style.css" type="text/css">
|
||||
<link rel="stylesheet" href="style.css" type="text/css">
|
||||
<script src="../lib/OpenLayers.js"></script>
|
||||
<script src="osm-marker-popup.js"></script>
|
||||
</head>
|
||||
<body onload="init()">
|
||||
<h1 id="title">OSM with Marker and Popup</h1>
|
||||
<p id="shortdesc">
|
||||
Demonstrate use of an OSM layer with a marker and a popup.
|
||||
</p>
|
||||
<div id="tags">
|
||||
openstreetmap osm marker popup
|
||||
</div>
|
||||
<div id="map" class="smallmap"></div>
|
||||
<div id="docs">
|
||||
<p>
|
||||
A common use case for OpenLayers is to display a marker at a
|
||||
location on the map, and add some information in a popup. It
|
||||
is also easy to add a tooltip with a short description.
|
||||
See the <a href="osm-marker-popup.js" target="_blank">
|
||||
osm-marker-popup.js source</a> to see how this is done.
|
||||
</p>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
39
examples/osm-marker-popup.js
Normal file
39
examples/osm-marker-popup.js
Normal file
@@ -0,0 +1,39 @@
|
||||
var map;
|
||||
function init() {
|
||||
|
||||
// The overlay layer for our marker, with a simple diamond as symbol
|
||||
var overlay = new OpenLayers.Layer.Vector('Overlay', {
|
||||
styleMap: new OpenLayers.StyleMap({
|
||||
externalGraphic: '../img/marker.png',
|
||||
graphicWidth: 20, graphicHeight: 24, graphicYOffset: -24,
|
||||
title: '${tooltip}'
|
||||
})
|
||||
});
|
||||
|
||||
// The location of our marker and popup. We usually think in geographic
|
||||
// coordinates ('EPSG:4326'), but the map is projected ('EPSG:3857').
|
||||
var myLocation = new OpenLayers.Geometry.Point(10.2, 48.9)
|
||||
.transform('EPSG:4326', 'EPSG:3857');
|
||||
|
||||
// We add the marker with a tooltip text to the overlay
|
||||
overlay.addFeatures([
|
||||
new OpenLayers.Feature.Vector(myLocation, {tooltip: 'OpenLayers'})
|
||||
]);
|
||||
|
||||
// A popup with some information about our location
|
||||
var popup = new OpenLayers.Popup.FramedCloud("Popup",
|
||||
myLocation.getBounds().getCenterLonLat(), null,
|
||||
'<a target="_blank" href="http://openlayers.org/">We</a> ' +
|
||||
'could be here.<br>Or elsewhere.', null,
|
||||
true // <-- true if we want a close (X) button, false otherwise
|
||||
);
|
||||
|
||||
// Finally we create the map
|
||||
map = new OpenLayers.Map({
|
||||
div: "map", projection: "EPSG:3857",
|
||||
layers: [new OpenLayers.Layer.OSM(), overlay],
|
||||
center: myLocation.getBounds().getCenterLonLat(), zoom: 15
|
||||
});
|
||||
// and add the popup to it.
|
||||
map.addPopup(popup);
|
||||
}
|
||||
@@ -37,10 +37,8 @@
|
||||
function init() {
|
||||
map = new OpenLayers.Map('map');
|
||||
var base = new OpenLayers.Layer.WMS("OpenLayers WMS",
|
||||
["http://t3.tilecache.osgeo.org/wms-c/Basic.py",
|
||||
"http://t2.tilecache.osgeo.org/wms-c/Basic.py",
|
||||
"http://t1.tilecache.osgeo.org/wms-c/Basic.py"],
|
||||
{layers: 'satellite'}
|
||||
"http://vmap0.tiles.osgeo.org/wms/vmap0",
|
||||
{layers: 'basic'}
|
||||
);
|
||||
|
||||
var style = new OpenLayers.Style({
|
||||
|
||||
@@ -20,15 +20,15 @@
|
||||
<h1 id="title">Web Map Tile Service (WMTS) Capabilities Parsing</h1>
|
||||
<div id="tags">
|
||||
wmts, capabilities, getcapabilities
|
||||
</div>
|
||||
</div>
|
||||
<p id="shortdesc">
|
||||
The WMTS Capabilities format allows for parsing of capabilities
|
||||
documents from OGC Web Map Tile Service (WMTS) version 1.0.0
|
||||
documents from OGC Web Map Tile Service (WMTS) version 1.0.0
|
||||
implementations.
|
||||
</p>
|
||||
|
||||
|
||||
<div id="map" class="smallmap"></div>
|
||||
|
||||
|
||||
<div id="docs">
|
||||
<p>
|
||||
This example creates an OpenLayers.Layer.WMTS layer to based
|
||||
|
||||
@@ -3,13 +3,13 @@ OpenLayers.ProxyHost = "/proxy/?url=";
|
||||
var map, format;
|
||||
|
||||
function init() {
|
||||
|
||||
|
||||
format = new OpenLayers.Format.WMTSCapabilities({
|
||||
/**
|
||||
* This particular service is not in compliance with the WMTS spec and
|
||||
* is providing coordinates in y, x order regardless of the CRS. To
|
||||
* work around this, we can provide the format a table of CRS URN that
|
||||
* should be considered y, x order. These will extend the defaults on
|
||||
* work around this, we can provide the format a table of CRS URN that
|
||||
* should be considered y, x order. These will extend the defaults on
|
||||
* the format.
|
||||
*/
|
||||
yx: {
|
||||
@@ -38,22 +38,21 @@ function init() {
|
||||
isBaseLayer: false
|
||||
});
|
||||
map.addLayer(layer);
|
||||
},
|
||||
},
|
||||
failure: function() {
|
||||
alert("Trouble getting capabilities doc");
|
||||
OpenLayers.Console.error.apply(OpenLayers.Console, arguments);
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
map = new OpenLayers.Map({
|
||||
div: "map",
|
||||
projection: "EPSG:900913"
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
var osm = new OpenLayers.Layer.OSM();
|
||||
|
||||
map.addLayer(osm);
|
||||
map.addControl(new OpenLayers.Control.LayerSwitcher());
|
||||
map.setCenter(new OpenLayers.LonLat(-13677832, 5213272), 13);
|
||||
|
||||
}
|
||||
|
||||
@@ -6,27 +6,27 @@
|
||||
/**
|
||||
* @requires OpenLayers/Format/XML/VersionedOGC.js
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* Class: OpenLayers.Format.WMTSCapabilities
|
||||
* Read WMTS Capabilities.
|
||||
*
|
||||
*
|
||||
* Inherits from:
|
||||
* - <OpenLayers.Format.XML.VersionedOGC>
|
||||
*/
|
||||
OpenLayers.Format.WMTSCapabilities = OpenLayers.Class(OpenLayers.Format.XML.VersionedOGC, {
|
||||
|
||||
|
||||
/**
|
||||
* APIProperty: defaultVersion
|
||||
* {String} Version number to assume if none found. Default is "1.0.0".
|
||||
*/
|
||||
defaultVersion: "1.0.0",
|
||||
|
||||
|
||||
/**
|
||||
* APIProperty: yx
|
||||
* {Object} Members in the yx object are used to determine if a CRS URN
|
||||
* corresponds to a CRS with y,x axis order. Member names are CRS URNs
|
||||
* and values are boolean. By default, the following CRS URN are
|
||||
* and values are boolean. By default, the following CRS URN are
|
||||
* assumed to correspond to a CRS with y,x axis order:
|
||||
*
|
||||
* * urn:ogc:def:crs:EPSG::4326
|
||||
@@ -48,8 +48,8 @@ OpenLayers.Format.WMTSCapabilities = OpenLayers.Class(OpenLayers.Format.XML.Vers
|
||||
* APIMethod: read
|
||||
* Read capabilities data from a string, and return information about
|
||||
* the service (offering and observedProperty mostly).
|
||||
*
|
||||
* Parameters:
|
||||
*
|
||||
* Parameters:
|
||||
* data - {String} or {DOMElement} data to read/parse.
|
||||
*
|
||||
* Returns:
|
||||
@@ -61,36 +61,34 @@ OpenLayers.Format.WMTSCapabilities = OpenLayers.Class(OpenLayers.Format.XML.Vers
|
||||
* Create a WMTS layer given a capabilities object.
|
||||
*
|
||||
* Parameters:
|
||||
* capabilities - {Object} The object returned from a <read> call to this
|
||||
* capabilities - {Object} The object returned from a <read> call to this
|
||||
* format.
|
||||
* config - {Object} Configuration properties for the layer. Defaults for
|
||||
* the layer will apply if not provided.
|
||||
*
|
||||
* Required config properties:
|
||||
* layer - {String} The layer identifier.
|
||||
* matrixSet - {String} The matrix set identifier.
|
||||
*
|
||||
* Optional config properties:
|
||||
* matrixSet - {String} The matrix set identifier, required if there is
|
||||
* more than one matrix set in the layer capabilities.
|
||||
* style - {String} The name of the style
|
||||
* param - {Object} The dimensions values eg: {"Year": "2012"}
|
||||
*
|
||||
* Returns:
|
||||
* {<OpenLayers.Layer.WMTS>} A properly configured WMTS layer. Throws an
|
||||
* error if an incomplete config is provided. Returns undefined if no
|
||||
* layer could be created with the provided config.
|
||||
*/
|
||||
*/
|
||||
createLayer: function(capabilities, config) {
|
||||
var layer;
|
||||
|
||||
// confirm required properties are supplied in config
|
||||
var required = {
|
||||
layer: true,
|
||||
matrixSet: true
|
||||
};
|
||||
for (var prop in required) {
|
||||
if (!(prop in config)) {
|
||||
throw new Error("Missing property '" + prop + "' in layer configuration.");
|
||||
}
|
||||
if (!('layer' in config)) {
|
||||
throw new Error("Missing property 'layer' in configuration.");
|
||||
}
|
||||
|
||||
var contents = capabilities.contents;
|
||||
var matrixSet = contents.tileMatrixSets[config.matrixSet];
|
||||
|
||||
// find the layer definition with the given identifier
|
||||
var layers = contents.layers;
|
||||
@@ -101,32 +99,97 @@ OpenLayers.Format.WMTSCapabilities = OpenLayers.Class(OpenLayers.Format.XML.Vers
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (layerDef && matrixSet) {
|
||||
// get the default style for the layer
|
||||
var style;
|
||||
for (var i=0, ii=layerDef.styles.length; i<ii; ++i) {
|
||||
style = layerDef.styles[i];
|
||||
if (style.isDefault) {
|
||||
break;
|
||||
if (!layerDef) {
|
||||
throw new Error("Layer not found");
|
||||
}
|
||||
|
||||
// find the matrixSet definition
|
||||
var matrixSet;
|
||||
if (config.matrixSet) {
|
||||
matrixSet = contents.tileMatrixSets[config.matrixSet];
|
||||
} else if (layerDef.tileMatrixSetLinks.length == 1) {
|
||||
matrixSet = contents.tileMatrixSets[
|
||||
layerDef.tileMatrixSetLinks[0].tileMatrixSet];
|
||||
}
|
||||
if (!matrixSet) {
|
||||
throw new Error("matrixSet not found");
|
||||
}
|
||||
|
||||
// get the default style for the layer
|
||||
var style;
|
||||
for (var i=0, ii=layerDef.styles.length; i<ii; ++i) {
|
||||
style = layerDef.styles[i];
|
||||
if (style.isDefault) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
var requestEncoding = config.requestEncoding;
|
||||
if (!requestEncoding) {
|
||||
requestEncoding = "KVP";
|
||||
if (capabilities.operationsMetadata.GetTile.dcp.http) {
|
||||
var http = capabilities.operationsMetadata.GetTile.dcp.http;
|
||||
// Get first get method
|
||||
if (http.get[0].constraints) {
|
||||
var constraints = http.get[0].constraints;
|
||||
if (!constraints.GetEncoding.allowedValues.KVP &&
|
||||
constraints.GetEncoding.allowedValues.REST) {
|
||||
requestEncoding = "REST";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
layer = new OpenLayers.Layer.WMTS(
|
||||
OpenLayers.Util.applyDefaults(config, {
|
||||
url: config.requestEncoding === "REST" && layerDef.resourceUrl ?
|
||||
layerDef.resourceUrl.tile.template :
|
||||
capabilities.operationsMetadata.GetTile.dcp.http.get[0].url,
|
||||
name: layerDef.title,
|
||||
style: style.identifier,
|
||||
matrixIds: matrixSet.matrixIds,
|
||||
tileFullExtent: matrixSet.bounds
|
||||
})
|
||||
);
|
||||
}
|
||||
return layer;
|
||||
|
||||
var dimensions = [];
|
||||
var params = config.params || {};
|
||||
// to don't overwrite the changes in the applyDefaults
|
||||
delete config.params;
|
||||
for (var id = 0, ld = layerDef.dimensions.length ; id < ld ; id++) {
|
||||
var dimension = layerDef.dimensions[id];
|
||||
dimensions.push(dimension.identifier);
|
||||
if (!params.hasOwnProperty(dimension.identifier)) {
|
||||
params[dimension.identifier] = dimension['default'];
|
||||
}
|
||||
}
|
||||
|
||||
var projection = config.projection || matrixSet.supportedCRS.replace(
|
||||
/urn:ogc:def:crs:(\w+):(.*:)?(\w+)$/, "$1:$3");
|
||||
var units = config.units ||
|
||||
projection === "EPSG:4326" ? "degrees" : "m"
|
||||
|
||||
var resolutions = [];
|
||||
if (config.isBaseLayer !== false) {
|
||||
for (mid in matrixSet.matrixIds) {
|
||||
if (matrixSet.matrixIds.hasOwnProperty(mid)) {
|
||||
resolutions.push(
|
||||
matrixSet.matrixIds[mid].scaleDenominator * 0.28E-3
|
||||
/ OpenLayers.METERS_PER_INCH
|
||||
/ OpenLayers.INCHES_PER_UNIT[units]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return new OpenLayers.Layer.WMTS(
|
||||
OpenLayers.Util.applyDefaults(config, {
|
||||
url: requestEncoding === "REST" && layerDef.resourceUrl ?
|
||||
layerDef.resourceUrl.tile.template :
|
||||
capabilities.operationsMetadata.GetTile.dcp.http.get[0].url,
|
||||
requestEncoding: requestEncoding,
|
||||
name: layerDef.title,
|
||||
style: style.identifier,
|
||||
matrixIds: matrixSet.matrixIds,
|
||||
matrixSet: matrixSet.identifier,
|
||||
projection: projection,
|
||||
units: units,
|
||||
resolutions: config.isBaseLayer === false ? undefined :
|
||||
resolutions,
|
||||
tileFullExtent: matrixSet.bounds,
|
||||
dimensions: dimensions,
|
||||
params: params
|
||||
})
|
||||
);
|
||||
},
|
||||
|
||||
CLASS_NAME: "OpenLayers.Format.WMTSCapabilities"
|
||||
|
||||
CLASS_NAME: "OpenLayers.Format.WMTSCapabilities"
|
||||
|
||||
});
|
||||
|
||||
@@ -106,6 +106,7 @@ OpenLayers.Layer.WMTS = OpenLayers.Class(OpenLayers.Layer.Grid, {
|
||||
*
|
||||
* Matrix properties:
|
||||
* identifier - {String} The matrix identifier (required).
|
||||
* scaleDenominator - {Number} The matrix scale denominator.
|
||||
* topLeftCorner - {<OpenLayers.LonLat>} The top left corner of the
|
||||
* matrix. Must be provided if different than the layer <tileOrigin>.
|
||||
* tileWidth - {Number} The tile width for the matrix. Must be provided
|
||||
|
||||
@@ -43,15 +43,15 @@
|
||||
undefined,
|
||||
"ows:OperationsMetadata GetTile Constraints Get is correct");
|
||||
}
|
||||
|
||||
|
||||
function test_layers(t) {
|
||||
t.plan(37);
|
||||
var xml = document.getElementById("ogcsample").firstChild.nodeValue;
|
||||
var doc = new OpenLayers.Format.XML().read(xml);
|
||||
|
||||
|
||||
var obj = new OpenLayers.Format.WMTSCapabilities().read(doc);
|
||||
var contents = obj.contents;
|
||||
|
||||
|
||||
var numOfLayers = contents.layers.length;
|
||||
t.eq(numOfLayers, 1, "correct count of layers");
|
||||
|
||||
@@ -89,11 +89,11 @@
|
||||
t.eq(wgs84Bbox.top, 90.0, "wgs84BoudingBox top is correct");
|
||||
|
||||
t.eq(layer.resourceUrl.tile.format, "image/png", "resourceUrl.tile.format is correct");
|
||||
t.eq(layer.resourceUrl.tile.template, "http://www.example.com/wmts/coastlines/{TileMatrix}/{TileRow}/{TileCol}.png",
|
||||
t.eq(layer.resourceUrl.tile.template, "http://www.example.com/wmts/coastlines/{TileMatrix}/{TileRow}/{TileCol}.png",
|
||||
"resourceUrl.tile.template is correct");
|
||||
|
||||
t.eq(layer.resourceUrl.FeatureInfo.format, "application/gml+xml; version=3.1", "resourceUrl.FeatureInfo.format is correct");
|
||||
t.eq(layer.resourceUrl.FeatureInfo.template, "http://www.example.com/wmts/coastlines/{TileMatrixSet}/{TileMatrix}/{TileRow}/{TileCol}/{J}/{I}.xml",
|
||||
t.eq(layer.resourceUrl.FeatureInfo.template, "http://www.example.com/wmts/coastlines/{TileMatrixSet}/{TileMatrix}/{TileRow}/{TileCol}/{J}/{I}.xml",
|
||||
"resourceUrl.FeatureInfo.template is correct");
|
||||
|
||||
var dimensions = layer.dimensions;
|
||||
@@ -112,7 +112,7 @@
|
||||
t.plan(19);
|
||||
var xml = document.getElementById("ogcsample").firstChild.nodeValue;
|
||||
var doc = new OpenLayers.Format.XML().read(xml);
|
||||
|
||||
|
||||
var obj = new OpenLayers.Format.WMTSCapabilities().read(doc);
|
||||
|
||||
var tileMatrixSets = obj.contents.tileMatrixSets;
|
||||
@@ -138,54 +138,123 @@
|
||||
t.eq(bigWorld.matrixIds[1].topLeftCorner.lon, -180, "tileMatrix 1 topLeftCorner.lon is correct");
|
||||
t.eq(bigWorld.matrixIds[1].topLeftCorner.lat, 84, "tileMatrix 1 topLeftCorner.lat is correct");
|
||||
}
|
||||
|
||||
|
||||
function test_createLayer(t) {
|
||||
t.plan(7);
|
||||
|
||||
t.plan(27);
|
||||
|
||||
var format = new OpenLayers.Format.WMTSCapabilities();
|
||||
|
||||
var xml = document.getElementById("ogcsample").firstChild.nodeValue;
|
||||
var doc = new OpenLayers.Format.XML().read(xml);
|
||||
|
||||
|
||||
var caps = format.read(doc);
|
||||
var layer;
|
||||
|
||||
|
||||
var success = true;
|
||||
try {
|
||||
// incomplete config (missing matrixSet)
|
||||
// incomplete config (missing layer)
|
||||
layer = format.createLayer(caps, {
|
||||
layer: "coastlines"
|
||||
});
|
||||
} catch (err) {
|
||||
success = false;
|
||||
}
|
||||
t.ok(!success, "createLayer throws error if provided incomplete layer config");
|
||||
|
||||
|
||||
// bogus layer identifier
|
||||
layer = format.createLayer(caps, {
|
||||
layer: "foo",
|
||||
matrixSet: "BigWorld"
|
||||
});
|
||||
t.eq(layer, undefined, "createLayer returns undefined given bad layer identifier");
|
||||
|
||||
try {
|
||||
layer = format.createLayer(caps, {
|
||||
layer: "foo",
|
||||
matrixSet: "BigWorld"
|
||||
});
|
||||
} catch (err) {
|
||||
success = false;
|
||||
}
|
||||
t.ok(!success, "createLayer returns undefined given bad layer identifier");
|
||||
|
||||
// bogus matrixSet identifier
|
||||
layer = format.createLayer(caps, {
|
||||
layer: "coastlines",
|
||||
matrixSet: "TheWorld"
|
||||
});
|
||||
t.eq(layer, undefined, "createLayer returns undefined given bad matrixSet identifier");
|
||||
|
||||
try {
|
||||
layer = format.createLayer(caps, {
|
||||
layer: "coastlines",
|
||||
matrixSet: "TheWorld"
|
||||
});
|
||||
} catch (err) {
|
||||
success = false;
|
||||
}
|
||||
t.ok(!success, "createLayer returns undefined given bad matrixSet identifier");
|
||||
|
||||
layer = format.createLayer(caps, {
|
||||
layer: "coastlines",
|
||||
matrixSet: "BigWorld"
|
||||
});
|
||||
t.ok(layer instanceof OpenLayers.Layer.WMTS, "correct instance");
|
||||
|
||||
|
||||
// autodetect matrixSet
|
||||
layer = format.createLayer(caps, {
|
||||
layer: "coastlines"
|
||||
});
|
||||
t.ok(layer instanceof OpenLayers.Layer.WMTS, "correct instance, with autodetected matrixSet");
|
||||
|
||||
t.eq(layer.matrixIds.length, 2, "correct matrixIds length");
|
||||
t.eq(layer.name, "Coastlines", "correct layer title");
|
||||
t.eq(layer.style, "DarkBlue", "correct style identifier");
|
||||
t.eq(layer.requestEncoding, "KVP", "correct requestEncoding");
|
||||
|
||||
xml = document.getElementById("restsample").firstChild.nodeValue;
|
||||
doc = new OpenLayers.Format.XML().read(xml);
|
||||
caps = format.read(doc);
|
||||
layer = format.createLayer(caps, {
|
||||
layer: "ch.are.agglomerationen_isolierte_staedte-2000",
|
||||
matrixSet: "21781"
|
||||
});
|
||||
t.ok(layer instanceof OpenLayers.Layer.WMTS, "correct instance");
|
||||
t.eq(layer.url, "http://wmts.geo.admin.ch/1.0.0/ch.are.agglomerationen_isolierte_staedte-2000/default/{Time}/{TileMatrixSet}/{TileMatrix}/{TileRow}/{TileCol}.png", "correct url");
|
||||
t.eq(layer.matrixIds.length, 3, "correct matrixIds length");
|
||||
t.eq(layer.requestEncoding, "REST", "correct requestEncoding");
|
||||
t.eq(layer.name, "Agglomérations et villes isolées", "correct layer title");
|
||||
t.eq(layer.style, "ch.are.agglomerationen_isolierte_staedte-2000", "correct style identifier");
|
||||
t.eq(layer.projection.getCode(), "EPSG:21781", "correct projection");
|
||||
t.eq(layer.units, "m", "correct untis");
|
||||
t.eq(layer.resolutions.length, 3, "correct resolutions length");
|
||||
t.ok((layer.resolutions[0] - 4000) < 1, "correct first resolution");
|
||||
t.eq(layer.dimensions.length, 1, "correct dimensions length");
|
||||
t.eq(layer.dimensions[0], "Time", "correct dimensions");
|
||||
t.eq(layer.params['TIME'], "20090101", "correct params");
|
||||
|
||||
layer = format.createLayer(caps, {
|
||||
layer: "ch.are.agglomerationen_isolierte_staedte-2000",
|
||||
style: "toto",
|
||||
params: {"Time": "2012"}
|
||||
});
|
||||
t.eq(layer.matrixIds.length, 3, "correct matrixIds length");
|
||||
t.eq(layer.style, "toto", "correct style identifier");
|
||||
t.eq(layer.dimensions.length, 1, "correct dimensions length");
|
||||
t.eq(layer.dimensions[0], "Time", "correct dimensions");
|
||||
t.eq(layer.params['TIME'], "2012", "correct params");
|
||||
}
|
||||
|
||||
function test_parse_projection(t) {
|
||||
t.plan(2);
|
||||
|
||||
var format = new OpenLayers.Format.WMTSCapabilities();
|
||||
|
||||
var xml = document.getElementById("restsample-alternate-proj1").firstChild.nodeValue;
|
||||
var doc = new OpenLayers.Format.XML().read(xml);
|
||||
var caps = format.read(doc);
|
||||
var layer = format.createLayer(caps, {
|
||||
layer: "ch.are.agglomerationen_isolierte_staedte-2000",
|
||||
matrixSet: "21781"
|
||||
});
|
||||
t.eq(layer.projection.getCode(), "EPSG:21781", "correct projection");
|
||||
|
||||
xml = document.getElementById("restsample-alternate-proj2").firstChild.nodeValue;
|
||||
doc = new OpenLayers.Format.XML().read(xml);
|
||||
caps = format.read(doc);
|
||||
layer = format.createLayer(caps, {
|
||||
layer: "ch.are.agglomerationen_isolierte_staedte-2000",
|
||||
matrixSet: "21781"
|
||||
});
|
||||
t.eq(layer.projection.getCode(), "EPSG:21781", "correct projection");
|
||||
}
|
||||
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
@@ -300,15 +369,15 @@ http://schemas.opengis.net/wmts/1.0/examples/wmtsGetCapabilities_response.xml
|
||||
<TileMatrixSet>BigWorld</TileMatrixSet>
|
||||
</TileMatrixSetLink>
|
||||
</Layer>
|
||||
<TileMatrixSet>
|
||||
<TileMatrixSet>
|
||||
<ows:Identifier>BigWorld</ows:Identifier>
|
||||
<ows:SupportedCRS>urn:ogc:def:crs:OGC:1.3:CRS84</ows:SupportedCRS>
|
||||
<TileMatrix>
|
||||
<ows:Identifier>1e6</ows:Identifier>
|
||||
<ScaleDenominator>1e6</ScaleDenominator>
|
||||
<TopLeftCorner>-180 84</TopLeftCorner>
|
||||
<ScaleDenominator>1e6</ScaleDenominator>
|
||||
<TopLeftCorner>-180 84</TopLeftCorner>
|
||||
<TileWidth>256</TileWidth>
|
||||
<TileHeight>256</TileHeight>
|
||||
<TileHeight>256</TileHeight>
|
||||
<MatrixWidth>60000</MatrixWidth>
|
||||
<MatrixHeight>50000</MatrixHeight>
|
||||
</TileMatrix>
|
||||
@@ -354,5 +423,284 @@ http://schemas.opengis.net/wmts/1.0/examples/wmtsGetCapabilities_response.xml
|
||||
</Themes>
|
||||
</Capabilities>
|
||||
--></div>
|
||||
|
||||
<div id="restsample"><!--
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<Capabilities xmlns="http://www.opengis.net/wmts/1.0" xmlns:ows="http://www.opengis.net/ows/1.1" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:gml="http://www.opengis.net/gml" xsi:schemaLocation="http://www.opengis.net/wmts/1.0 http://schemas.opengis.net/wmts/1.0/wmtsGetCapabilities_response.xsd" version="1.0.0">
|
||||
<ows:ServiceIdentification>
|
||||
<ows:Title>Federal Geodata Infrastructure of Switzerland</ows:Title>
|
||||
<ows:Abstract>Some Geodata are subject to license and fees</ows:Abstract>
|
||||
<ows:Keywords>
|
||||
<ows:Keyword>FGDI</ows:Keyword>
|
||||
<ows:Keyword>Pixelkarte</ows:Keyword>
|
||||
<ows:Keyword>Switzerland</ows:Keyword>
|
||||
</ows:Keywords>
|
||||
<ows:ServiceType>OGC WMTS</ows:ServiceType>
|
||||
<ows:ServiceTypeVersion>1.0.0</ows:ServiceTypeVersion>
|
||||
<ows:Fees>yes</ows:Fees>
|
||||
<ows:AccessConstraints>license</ows:AccessConstraints>
|
||||
</ows:ServiceIdentification>
|
||||
<ows:ServiceProvider>
|
||||
<ows:ProviderName>swisstopo</ows:ProviderName>
|
||||
<ows:ProviderSite xlink:href="http://www.swisstopo.admin.ch"/>
|
||||
<ows:ServiceContact>
|
||||
<ows:IndividualName>David Oesch</ows:IndividualName>
|
||||
<ows:PositionName></ows:PositionName>
|
||||
<ows:ContactInfo>
|
||||
<ows:Phone>
|
||||
<ows:Voice>+41 (0)31 / 963 21 11</ows:Voice>
|
||||
<ows:Facsimile>+41 (0)31 / 963 24 59</ows:Facsimile>
|
||||
</ows:Phone>
|
||||
<ows:Address>
|
||||
<ows:DeliveryPoint>swisstopo</ows:DeliveryPoint>
|
||||
<ows:City>Bern</ows:City>
|
||||
<ows:AdministrativeArea>BE</ows:AdministrativeArea>
|
||||
<ows:PostalCode>3084</ows:PostalCode>
|
||||
<ows:Country>Switzerland</ows:Country>
|
||||
<ows:ElectronicMailAddress/>
|
||||
</ows:Address>
|
||||
</ows:ContactInfo>
|
||||
</ows:ServiceContact>
|
||||
</ows:ServiceProvider>
|
||||
<ows:OperationsMetadata>
|
||||
<ows:Operation name="GetCapabilities">
|
||||
<ows:DCP>
|
||||
<ows:HTTP>
|
||||
<ows:Get xlink:href="http://wmts.geo.admin.ch/1.0.0/WMTSCapabilities.xml">
|
||||
<ows:Constraint name="GetEncoding">
|
||||
<ows:AllowedValues>
|
||||
<ows:Value>REST</ows:Value>
|
||||
</ows:AllowedValues>
|
||||
</ows:Constraint>
|
||||
</ows:Get>
|
||||
</ows:HTTP>
|
||||
</ows:DCP>
|
||||
</ows:Operation>
|
||||
<ows:Operation name="GetTile">
|
||||
<ows:DCP>
|
||||
<ows:HTTP>
|
||||
<ows:Get xlink:href="http://wmts.geo.admin.ch/">
|
||||
<ows:Constraint name="GetEncoding">
|
||||
<ows:AllowedValues>
|
||||
<ows:Value>REST</ows:Value>
|
||||
</ows:AllowedValues>
|
||||
</ows:Constraint>
|
||||
</ows:Get>
|
||||
</ows:HTTP>
|
||||
</ows:DCP>
|
||||
</ows:Operation>
|
||||
</ows:OperationsMetadata>
|
||||
<Contents>
|
||||
<Layer>
|
||||
<ows:Title>Agglomérations et villes isolées</ows:Title>
|
||||
<ows:Abstract>Les agglomérations et villes isolées (communes non rattachées à une agglomération et comptant au moins 10`000 habitants) font partie des régions d’analyse de la statistique suisse. Ce niveau géographique est défini depuis plus de 100 ans, afin de mesurer l’urbanisation, phénomène fondamental structurant l’organisation du territoire. Sa fonction principale est de permettre une comparaison spatiale entre des espaces urbains inégalement délimités sur le plan institutionnel. Une version ancienne est appliquée pour la première fois en 1930, puis révisée en 1984 et 1990, toujours sur la base des recensements de la population. La version actuelle classe les 2896 communes de Suisse (état 2000) selon leur appartenance ou pas à une agglomération ou ville isolée en fonction de critères statistiques (Etat et évolution de la population, lien de continuité de la zone bâtie, rapport entre population active occupée et population résidante, structure économique et flux de pendulaires). Les agglomérations et les villes isolées forment l`espace urbain, les territoires restant l`espace rural. La définition des agglomérations de l’OFS n’a pas valeur d’obligation légale.</ows:Abstract>
|
||||
<ows:WGS84BoundingBox>
|
||||
<ows:LowerCorner>5.140242 45.398181</ows:LowerCorner>
|
||||
<ows:UpperCorner>11.47757 48.230651</ows:UpperCorner>
|
||||
</ows:WGS84BoundingBox>
|
||||
<ows:Identifier>ch.are.agglomerationen_isolierte_staedte-2000</ows:Identifier>
|
||||
<ows:Metadata xlink:href="http://www.swisstopo.admin.ch/SITiled/world/AdminBoundaries/metadata.htm"/>
|
||||
<Style>
|
||||
<ows:Title>Agglomérations et villes isolées</ows:Title>
|
||||
<ows:Identifier>ch.are.agglomerationen_isolierte_staedte-2000</ows:Identifier>
|
||||
<LegendURL format="image/png" xlink:href="http://api.geo.admin.ch/legend/ch.are.agglomerationen_isolierte_staedte-2000_fr.png" />
|
||||
</Style>
|
||||
<Format>image/png</Format>
|
||||
<Dimension>
|
||||
<ows:Identifier>Time</ows:Identifier>
|
||||
<Default>20090101</Default>
|
||||
<Value>20090101</Value>
|
||||
</Dimension>
|
||||
<TileMatrixSetLink>
|
||||
<TileMatrixSet>21781</TileMatrixSet>
|
||||
</TileMatrixSetLink>
|
||||
<ResourceURL format="image/png" resourceType="tile" template="http://wmts.geo.admin.ch/1.0.0/ch.are.agglomerationen_isolierte_staedte-2000/default/{Time}/{TileMatrixSet}/{TileMatrix}/{TileRow}/{TileCol}.png"/>
|
||||
</Layer>
|
||||
<TileMatrixSet>
|
||||
<ows:Identifier>21781</ows:Identifier>
|
||||
<ows:SupportedCRS>urn:ogc:def:crs:EPSG::21781</ows:SupportedCRS>
|
||||
<TileMatrix>
|
||||
<ows:Identifier>0</ows:Identifier>
|
||||
<ScaleDenominator>14285750.5715</ScaleDenominator>
|
||||
<TopLeftCorner>420000.0 350000.0</TopLeftCorner>
|
||||
<TileWidth>256</TileWidth>
|
||||
<TileHeight>256</TileHeight>
|
||||
<MatrixWidth>1</MatrixWidth>
|
||||
<MatrixHeight>1</MatrixHeight>
|
||||
</TileMatrix>
|
||||
<TileMatrix>
|
||||
<ows:Identifier>8</ows:Identifier>
|
||||
<ScaleDenominator>7142875.28575</ScaleDenominator>
|
||||
<TopLeftCorner>420000.0 350000.0</TopLeftCorner>
|
||||
<TileWidth>256</TileWidth>
|
||||
<TileHeight>256</TileHeight>
|
||||
<MatrixWidth>1</MatrixWidth>
|
||||
<MatrixHeight>1</MatrixHeight>
|
||||
</TileMatrix>
|
||||
<TileMatrix>
|
||||
<ows:Identifier>12</ows:Identifier>
|
||||
<ScaleDenominator>3571437.64288</ScaleDenominator>
|
||||
<TopLeftCorner>420000.0 350000.0</TopLeftCorner>
|
||||
<TileWidth>256</TileWidth>
|
||||
<TileHeight>256</TileHeight>
|
||||
<MatrixWidth>2</MatrixWidth>
|
||||
<MatrixHeight>2</MatrixHeight>
|
||||
</TileMatrix>
|
||||
</TileMatrixSet>
|
||||
</Contents>
|
||||
<ServiceMetadataURL xlink:href="http://www.opengis.uab.es/SITiled/world/1.0.0/WMTSCapabilities.xml"/>
|
||||
</Capabilities>
|
||||
--></div>
|
||||
|
||||
<div id="restsample-alternate-proj1"><!--
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<Capabilities xmlns="http://www.opengis.net/wmts/1.0" xmlns:ows="http://www.opengis.net/ows/1.1" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:gml="http://www.opengis.net/gml" xsi:schemaLocation="http://www.opengis.net/wmts/1.0 http://schemas.opengis.net/wmts/1.0/wmtsGetCapabilities_response.xsd" version="1.0.0">
|
||||
<ows:OperationsMetadata>
|
||||
<ows:Operation name="GetCapabilities">
|
||||
<ows:DCP>
|
||||
<ows:HTTP>
|
||||
<ows:Get xlink:href="http://wmts.geo.admin.ch/1.0.0/WMTSCapabilities.xml">
|
||||
<ows:Constraint name="GetEncoding">
|
||||
<ows:AllowedValues>
|
||||
<ows:Value>REST</ows:Value>
|
||||
</ows:AllowedValues>
|
||||
</ows:Constraint>
|
||||
</ows:Get>
|
||||
</ows:HTTP>
|
||||
</ows:DCP>
|
||||
</ows:Operation>
|
||||
<ows:Operation name="GetTile">
|
||||
<ows:DCP>
|
||||
<ows:HTTP>
|
||||
<ows:Get xlink:href="http://wmts.geo.admin.ch/">
|
||||
<ows:Constraint name="GetEncoding">
|
||||
<ows:AllowedValues>
|
||||
<ows:Value>REST</ows:Value>
|
||||
</ows:AllowedValues>
|
||||
</ows:Constraint>
|
||||
</ows:Get>
|
||||
</ows:HTTP>
|
||||
</ows:DCP>
|
||||
</ows:Operation>
|
||||
</ows:OperationsMetadata>
|
||||
<Contents>
|
||||
<Layer>
|
||||
<ows:Title>Agglomérations et villes isolées</ows:Title>
|
||||
<ows:Abstract>Les agglomérations et villes isolées (communes non rattachées à une agglomération et comptant au moins 10`000 habitants) font partie des régions d’analyse de la statistique suisse. Ce niveau géographique est défini depuis plus de 100 ans, afin de mesurer l’urbanisation, phénomène fondamental structurant l’organisation du territoire. Sa fonction principale est de permettre une comparaison spatiale entre des espaces urbains inégalement délimités sur le plan institutionnel. Une version ancienne est appliquée pour la première fois en 1930, puis révisée en 1984 et 1990, toujours sur la base des recensements de la population. La version actuelle classe les 2896 communes de Suisse (état 2000) selon leur appartenance ou pas à une agglomération ou ville isolée en fonction de critères statistiques (Etat et évolution de la population, lien de continuité de la zone bâtie, rapport entre population active occupée et population résidante, structure économique et flux de pendulaires). Les agglomérations et les villes isolées forment l`espace urbain, les territoires restant l`espace rural. La définition des agglomérations de l’OFS n’a pas valeur d’obligation légale.</ows:Abstract>
|
||||
<ows:WGS84BoundingBox>
|
||||
<ows:LowerCorner>5.140242 45.398181</ows:LowerCorner>
|
||||
<ows:UpperCorner>11.47757 48.230651</ows:UpperCorner>
|
||||
</ows:WGS84BoundingBox>
|
||||
<ows:Identifier>ch.are.agglomerationen_isolierte_staedte-2000</ows:Identifier>
|
||||
<ows:Metadata xlink:href="http://www.swisstopo.admin.ch/SITiled/world/AdminBoundaries/metadata.htm"/>
|
||||
<Style>
|
||||
<ows:Title>Agglomérations et villes isolées</ows:Title>
|
||||
<ows:Identifier>ch.are.agglomerationen_isolierte_staedte-2000</ows:Identifier>
|
||||
<LegendURL format="image/png" xlink:href="http://api.geo.admin.ch/legend/ch.are.agglomerationen_isolierte_staedte-2000_fr.png" />
|
||||
</Style>
|
||||
<Format>image/png</Format>
|
||||
<Dimension>
|
||||
<ows:Identifier>Time</ows:Identifier>
|
||||
<Default>20090101</Default>
|
||||
<Value>20090101</Value>
|
||||
</Dimension>
|
||||
<TileMatrixSetLink>
|
||||
<TileMatrixSet>21781</TileMatrixSet>
|
||||
</TileMatrixSetLink>
|
||||
<ResourceURL format="image/png" resourceType="tile" template="http://wmts.geo.admin.ch/1.0.0/ch.are.agglomerationen_isolierte_staedte-2000/default/{Time}/{TileMatrixSet}/{TileMatrix}/{TileRow}/{TileCol}.png"/>
|
||||
</Layer>
|
||||
<TileMatrixSet>
|
||||
<ows:Identifier>21781</ows:Identifier>
|
||||
<ows:SupportedCRS>urn:ogc:def:crs:EPSG:21781</ows:SupportedCRS>
|
||||
<TileMatrix>
|
||||
<ows:Identifier>0</ows:Identifier>
|
||||
<ScaleDenominator>14285750.5715</ScaleDenominator>
|
||||
<TopLeftCorner>420000.0 350000.0</TopLeftCorner>
|
||||
<TileWidth>256</TileWidth>
|
||||
<TileHeight>256</TileHeight>
|
||||
<MatrixWidth>1</MatrixWidth>
|
||||
<MatrixHeight>1</MatrixHeight>
|
||||
</TileMatrix>
|
||||
</TileMatrixSet>
|
||||
</Contents>
|
||||
<ServiceMetadataURL xlink:href="http://www.opengis.uab.es/SITiled/world/1.0.0/WMTSCapabilities.xml"/>
|
||||
</Capabilities>
|
||||
--></div>
|
||||
|
||||
<div id="restsample-alternate-proj2"><!--
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<Capabilities xmlns="http://www.opengis.net/wmts/1.0" xmlns:ows="http://www.opengis.net/ows/1.1" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:gml="http://www.opengis.net/gml" xsi:schemaLocation="http://www.opengis.net/wmts/1.0 http://schemas.opengis.net/wmts/1.0/wmtsGetCapabilities_response.xsd" version="1.0.0">
|
||||
<ows:OperationsMetadata>
|
||||
<ows:Operation name="GetCapabilities">
|
||||
<ows:DCP>
|
||||
<ows:HTTP>
|
||||
<ows:Get xlink:href="http://wmts.geo.admin.ch/1.0.0/WMTSCapabilities.xml">
|
||||
<ows:Constraint name="GetEncoding">
|
||||
<ows:AllowedValues>
|
||||
<ows:Value>REST</ows:Value>
|
||||
</ows:AllowedValues>
|
||||
</ows:Constraint>
|
||||
</ows:Get>
|
||||
</ows:HTTP>
|
||||
</ows:DCP>
|
||||
</ows:Operation>
|
||||
<ows:Operation name="GetTile">
|
||||
<ows:DCP>
|
||||
<ows:HTTP>
|
||||
<ows:Get xlink:href="http://wmts.geo.admin.ch/">
|
||||
<ows:Constraint name="GetEncoding">
|
||||
<ows:AllowedValues>
|
||||
<ows:Value>REST</ows:Value>
|
||||
</ows:AllowedValues>
|
||||
</ows:Constraint>
|
||||
</ows:Get>
|
||||
</ows:HTTP>
|
||||
</ows:DCP>
|
||||
</ows:Operation>
|
||||
</ows:OperationsMetadata>
|
||||
<Contents>
|
||||
<Layer>
|
||||
<ows:Title>Agglomérations et villes isolées</ows:Title>
|
||||
<ows:Abstract>Les agglomérations et villes isolées (communes non rattachées à une agglomération et comptant au moins 10`000 habitants) font partie des régions d’analyse de la statistique suisse. Ce niveau géographique est défini depuis plus de 100 ans, afin de mesurer l’urbanisation, phénomène fondamental structurant l’organisation du territoire. Sa fonction principale est de permettre une comparaison spatiale entre des espaces urbains inégalement délimités sur le plan institutionnel. Une version ancienne est appliquée pour la première fois en 1930, puis révisée en 1984 et 1990, toujours sur la base des recensements de la population. La version actuelle classe les 2896 communes de Suisse (état 2000) selon leur appartenance ou pas à une agglomération ou ville isolée en fonction de critères statistiques (Etat et évolution de la population, lien de continuité de la zone bâtie, rapport entre population active occupée et population résidante, structure économique et flux de pendulaires). Les agglomérations et les villes isolées forment l`espace urbain, les territoires restant l`espace rural. La définition des agglomérations de l’OFS n’a pas valeur d’obligation légale.</ows:Abstract>
|
||||
<ows:WGS84BoundingBox>
|
||||
<ows:LowerCorner>5.140242 45.398181</ows:LowerCorner>
|
||||
<ows:UpperCorner>11.47757 48.230651</ows:UpperCorner>
|
||||
</ows:WGS84BoundingBox>
|
||||
<ows:Identifier>ch.are.agglomerationen_isolierte_staedte-2000</ows:Identifier>
|
||||
<ows:Metadata xlink:href="http://www.swisstopo.admin.ch/SITiled/world/AdminBoundaries/metadata.htm"/>
|
||||
<Style>
|
||||
<ows:Title>Agglomérations et villes isolées</ows:Title>
|
||||
<ows:Identifier>ch.are.agglomerationen_isolierte_staedte-2000</ows:Identifier>
|
||||
<LegendURL format="image/png" xlink:href="http://api.geo.admin.ch/legend/ch.are.agglomerationen_isolierte_staedte-2000_fr.png" />
|
||||
</Style>
|
||||
<Format>image/png</Format>
|
||||
<Dimension>
|
||||
<ows:Identifier>Time</ows:Identifier>
|
||||
<Default>20090101</Default>
|
||||
<Value>20090101</Value>
|
||||
</Dimension>
|
||||
<TileMatrixSetLink>
|
||||
<TileMatrixSet>21781</TileMatrixSet>
|
||||
</TileMatrixSetLink>
|
||||
<ResourceURL format="image/png" resourceType="tile" template="http://wmts.geo.admin.ch/1.0.0/ch.are.agglomerationen_isolierte_staedte-2000/default/{Time}/{TileMatrixSet}/{TileMatrix}/{TileRow}/{TileCol}.png"/>
|
||||
</Layer>
|
||||
<TileMatrixSet>
|
||||
<ows:Identifier>21781</ows:Identifier>
|
||||
<ows:SupportedCRS>urn:ogc:def:crs:EPSG:1.0:21781</ows:SupportedCRS>
|
||||
<TileMatrix>
|
||||
<ows:Identifier>0</ows:Identifier>
|
||||
<ScaleDenominator>14285750.5715</ScaleDenominator>
|
||||
<TopLeftCorner>420000.0 350000.0</TopLeftCorner>
|
||||
<TileWidth>256</TileWidth>
|
||||
<TileHeight>256</TileHeight>
|
||||
<MatrixWidth>1</MatrixWidth>
|
||||
<MatrixHeight>1</MatrixHeight>
|
||||
</TileMatrix>
|
||||
</TileMatrixSet>
|
||||
</Contents>
|
||||
<ServiceMetadataURL xlink:href="http://www.opengis.uab.es/SITiled/world/1.0.0/WMTSCapabilities.xml"/>
|
||||
</Capabilities>
|
||||
--></div>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
|
||||
Reference in New Issue
Block a user