github.com/go-spatial/go-wfs@v0.1.4-0.20190401000911-c9fba2bb5188/wfs3/html_templates.go (about)

     1  ///////////////////////////////////////////////////////////////////////////////
     2  //
     3  // The MIT License (MIT)
     4  // Copyright (c) 2018 Tom Kralidis
     5  //
     6  // Permission is hereby granted, free of charge, to any person obtaining a copy
     7  // of this software and associated documentation files (the "Software"), to
     8  // deal in the Software without restriction, including without limitation the
     9  // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
    10  // sell copies of the Software, and to permit persons to whom the Software is
    11  // furnished to do so, subject to the following conditions:
    12  //
    13  // The above copyright notice and this permission notice shall be included in
    14  // all copies or substantial portions of the Software.
    15  //
    16  // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
    17  // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
    18  // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
    19  // IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
    20  // DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
    21  // OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
    22  // USE OR OTHER DEALINGS IN THE SOFTWARE.
    23  //
    24  ///////////////////////////////////////////////////////////////////////////////
    25  
    26  package wfs3
    27  
    28  var tmpl_base = `<!doctype html>
    29  <html lang="en">
    30  	<head>
    31  	<meta charset="utf-8">
    32  	<title>{{ .config.Metadata.Identification.Title }}</title>
    33  	{{ range .links }}
    34  	<link rel="{{ .Rel }}" type="application/json" href="{{ .Href }}"/>
    35  	{{ end }}
    36  	<link rel="stylesheet" href="https://openlayers.org/en/v4.6.5/css/ol.css" type="text/css">
    37  	<script src="https://openlayers.org/en/v4.6.5/build/ol.js"></script>
    38  	<style>
    39  		.map {
    40  			height: 400px;
    41  			width: 100%;
    42  			margin-bottom: 10px;
    43  		}
    44  		.arrow_box {
    45  			border-radius: 5px;
    46  			padding: 10px;
    47  		}
    48  		.arrow_box {
    49  			position: relative;
    50  			background: #fff;
    51  			border: 1px solid #003c88;
    52  		}
    53  		.arrow_box:after, .arrow_box:before {
    54  			top: 100%;
    55  			left: 50%;
    56  			border: solid transparent;
    57  			content: " ";
    58  			height: 0;
    59  			width: 0;
    60  			position: absolute;
    61  			pointer-events: none;
    62  		}
    63  		.arrow_box:after {
    64  			border-color: rgba(255, 255, 255, 0);
    65  			border-top-color: #fff;
    66  			border-width: 10px;
    67  			margin-left: -10px;
    68  		}
    69  		.arrow_box:before {
    70  			border-color: rgba(153, 153, 153, 0);
    71  			border-top-color: #003c88;
    72  			border-width: 11px;
    73  			margin-left: -11px;
    74  		}
    75  	</style>
    76  	<script>
    77  		var image = new ol.style.Circle({
    78  			radius: 5,
    79  			fill: new ol.style.Fill({
    80  				color: 'rgb(255, 0, 0)'
    81  			}),
    82  			stroke: new ol.style.Stroke({color: 'red', width: 1})
    83  		});
    84  		var styles = {
    85  			'Point': new ol.style.Style({
    86  				image: image
    87  			}),
    88  			'LineString': new ol.style.Style({
    89  				stroke: new ol.style.Stroke({
    90  					color: 'green',
    91  					width: 1
    92  				})
    93  			}),
    94  			'MultiLineString': new ol.style.Style({
    95  				stroke: new ol.style.Stroke({
    96  					color: 'green',
    97  					width: 1
    98  				})
    99  			}),
   100  			'MultiPoint': new ol.style.Style({
   101  				image: image
   102  			}),
   103  			'MultiPolygon': new ol.style.Style({
   104  				stroke: new ol.style.Stroke({
   105  					color: 'yellow',
   106  					width: 1
   107  				}),
   108  				fill: new ol.style.Fill({
   109  					color: 'rgba(255, 255, 0, 0.1)'
   110  				})
   111  			}),
   112  			'Polygon': new ol.style.Style({
   113  				stroke: new ol.style.Stroke({
   114  					color: 'blue',
   115  					lineDash: [4],
   116  					width: 3
   117  				}),
   118  				fill: new ol.style.Fill({
   119  					color: 'rgba(0, 0, 255, 0.1)'
   120  				})
   121  			}),
   122  			'GeometryCollection': new ol.style.Style({
   123  				stroke: new ol.style.Stroke({
   124  					color: 'magenta',
   125  					width: 2
   126  				}),
   127  				fill: new ol.style.Fill({
   128  					color: 'magenta'
   129  				}),
   130  				image: new ol.style.Circle({
   131  					radius: 10,
   132  					fill: null,
   133  					stroke: new ol.style.Stroke({
   134  						color: 'magenta'
   135  					})
   136  				})
   137  			}),
   138  			'Circle': new ol.style.Style({
   139  				stroke: new ol.style.Stroke({
   140  					color: 'red',
   141  					width: 2
   142  				}),
   143  				fill: new ol.style.Fill({
   144  					color: 'rgba(255,0,0,0.2)'
   145  				})
   146  			})
   147  		};
   148  		var styleFunction = function(feature) {
   149  			return styles[feature.getGeometry().getType()];
   150  		};
   151  	</script>
   152  	</head>
   153  	<body>
   154  		<header>
   155  			<h1><a href="{{ .config.Server.URLBasePath }}?f=text/html">{{ .config.Metadata.Identification.Title }}</a><a href="{{ .config.Server.URLBasePath }}"><img src="https://image.flaticon.com/icons/svg/136/136443.svg" width="50" height="50"/></a></h1>
   156  			<span itemprop="description">{{ .config.Metadata.Identification.Description }}</span>
   157  		</header>
   158  		<hr/>
   159  		{{ .body }}
   160  		<hr/>
   161  		<footer>Powered by <a title="jivan" href="https://github.com/go-spatial/jivan">jivan</a><img width="50" height="50" src="https://raw.githubusercontent.com/go-spatial/branding/master/go-spatial.png"/></footer>
   162  	</body>
   163  </html>`
   164  
   165  // The /api/ endpoint doesn't support text/html
   166  var tmpl_root = `
   167  <h2><a href="conformance?f=text/html">Conformance</a></h2>
   168  <h2><a href="collections?f=text/html">Collections</a></h2>
   169  <h2>Links</h2>
   170  	<ul>
   171  	{{ range .data.Links }}
   172  		{{ if (eq .Rel "service") }}
   173  			<li><a href="{{ .Href }}">{{ .Href }}</a></li>
   174  		{{ else }}
   175  			<li><a href="{{ .Href }}?f=text/html">{{ .Href }}?f=text/html</a></li>
   176  		{{ end }}
   177  	{{ end }}
   178  	</ul>`
   179  
   180  var tmpl_conformance = `
   181  <h2>Conformance <a href="{{ .config.Server.URLBasePath }}conformance"><img src="https://image.flaticon.com/icons/svg/136/136443.svg" width="50" height="50"/></a></h2>
   182          <ul>
   183          {{ range .data.ConformsTo }}
   184  	        <li><a href="{{ . }}">{{ . }}</a></li>
   185          {{ end }}
   186          </ul>`
   187  
   188  var tmpl_collections = `
   189  <h2>Collections <a href="{{ .config.Server.URLBasePath }}collections"><img src="https://image.flaticon.com/icons/svg/136/136443.svg" width="50" height="50"/></a></h2>
   190  	<ul>
   191  	{{ range .data.Collections }}
   192  		<li><a href="./collections/{{ .Name }}?f=text/html">{{ .Name }}</a></li>
   193  	{{ end }}
   194  	</ul>`
   195  
   196  var tmpl_collection = `
   197  <h2>{{ .data.Name }} <a href="{{ .config.Server.URLBasePath }}collections/{{ .data.Name }}"><img src="https://image.flaticon.com/icons/svg/136/136443.svg" width="50" height="50"/></a></h2>
   198  	<span>{{ .data.Description }}</span>
   199  	<div><a href="./{{ .data.Name }}/items?f=text/html">Browse Features</a></div>
   200  	<h2>Links</h2>
   201  	<ul>
   202  		{{ range .data.Links }}
   203  		<li><a href="{{ .Href }}">{{ .Href }}</a></li>
   204  		{{ end }}
   205  	</ul>`
   206  
   207  var tmpl_collection_features = `
   208  <link rel="stylesheet" href="https://openlayers.org/en/v4.6.5/css/ol.css" type="text/css">
   209  <script src="https://openlayers.org/en/v4.6.5/build/ol.js"></script>
   210  <h2>Features <a href="items"><img src="https://image.flaticon.com/icons/svg/136/136443.svg" width="50" height="50"/></a></h2>
   211  	{{ range .data.Links }}
   212  		{{ if (eq .Rel "self") }}
   213          		<h2><a href="{{ .Href }}">Collection</a></h2>
   214  		{{ end }}
   215  		{{ if (eq .Rel "alternate") }}
   216          		<h2><a href="{{ .Href }}"><img src="https://image.flaticon.com/icons/svg/136/136443.svg" width="50" height="50"/></a></h2>
   217  		{{ end }}
   218  	{{ end }}
   219  	<h2>Links</h2>
   220  	{{ range .data.Links }}
   221  		{{ if (eq .Rel "prev") }}
   222  		<span><a href="{{ .Href }}&amp;f=text/html">Prev</a></span>
   223  		{{ end }}
   224  		{{ if (eq .Rel "next") }}
   225  		<span><a href="{{ .Href }}&amp;f=text/html">Next</a></span>
   226  		{{ end }}
   227  	{{ end }}
   228  	<table>
   229  		<tr>
   230  			<td>
   231  	<ul>
   232  	{{ range .data.Features }}
   233  		<li><a href="items/{{ .ID }}?f=text/html">{{ .ID }}</a></li>
   234  	{{ end }}
   235  	</ul>
   236  			</td>
   237  			<td>
   238  				<div id="map" class="map"></div>
   239  				<div id="popup-container" class="arrow_box"></div>
   240  			</td>
   241  		</tr>
   242  	</table>
   243  	<script>
   244  		var geojsonObject = {{ .data }};
   245  
   246  		var vectorSource = new ol.source.Vector({
   247  			features: (new ol.format.GeoJSON()).readFeatures(geojsonObject, {
   248  				dataProjection: "EPSG:4326",
   249  				featureProjection: "EPSG:3857"
   250  			})
   251  		});
   252  		var vectorLayer = new ol.layer.Vector({
   253  			source: vectorSource,
   254  			style: styleFunction,
   255  		});
   256  
   257  		var map = new ol.Map({
   258  			layers: [
   259  				new ol.layer.Tile({
   260  					source: new ol.source.OSM()
   261  				}),
   262  				vectorLayer
   263  			],
   264  			target: 'map',
   265  			controls: ol.control.defaults({
   266  				attributionOptions: {
   267  					collapsible: false
   268  				}
   269  			}),
   270  			view: new ol.View({
   271  				zoom: -10
   272  			})
   273  		});
   274  		map.getView().fit(vectorLayer.getSource().getExtent(), map.getSize());
   275  
   276  		var overlay = new ol.Overlay({
   277  			element: document.getElementById('popup-container'),
   278  			positioning: 'bottom-center',
   279  			offset: [0, -10]
   280  		});
   281  		map.addOverlay(overlay);
   282  
   283  		map.on('click', function(e) {
   284  			overlay.setPosition();
   285  			var features = map.getFeaturesAtPixel(e.pixel);
   286  			if (features) {
   287  				var identifier = features[0].getId();
   288  				var coords = features[0].getGeometry().getCoordinates();
   289  				var hdms = ol.coordinate.toStringHDMS(ol.proj.toLonLat(coords));
   290  				var popup = '<a href="items/' + identifier + '?f=text/html">' + identifier + '</a>';
   291  				overlay.getElement().innerHTML = popup;
   292  				overlay.setPosition(coords);
   293  			}
   294  		});
   295  	</script>`
   296  
   297  var tmpl_collection_feature = `
   298  <link rel="stylesheet" href="https://openlayers.org/en/v4.6.5/css/ol.css" type="text/css">
   299  <script src="https://openlayers.org/en/v4.6.5/build/ol.js"></script>
   300  {{ range .data.Links }}
   301  	{{ if (eq .Rel "collection") }}
   302  		<h2><a href="{{ .Href }}">Collection</a></h2>
   303  	{{ end }}
   304  {{ end }}
   305  <h2>Feature <a href="{{ .data.ID }}"><img src="https://image.flaticon.com/icons/svg/136/136443.svg" width="50" height="50"/></a></h2>
   306  	<h2>Links</h2>
   307  	<table>
   308  		<tr>
   309  			<td>
   310  	<h3>Properties</h3>
   311  	<ul>
   312  	{{ range $key, $value := .data.Properties }}
   313  		<li>{{ $key }}: {{ $value }}</li>
   314  	{{ end }}
   315  	</ul>
   316  			</td>
   317  			<td>
   318  				<div id="map" class="map"></div>
   319  				<div id="popup-container" class="arrow_box"></div>
   320  			</td>
   321  		</tr>
   322  	</table>
   323  	<script>
   324  		var geojsonObject = {{ .data }};
   325  
   326  		var vectorSource = new ol.source.Vector({
   327  			features: (new ol.format.GeoJSON()).readFeatures(geojsonObject, {
   328  				dataProjection: "EPSG:4326",
   329  				featureProjection: "EPSG:3857"
   330  			})
   331  		});
   332  		var vectorLayer = new ol.layer.Vector({
   333  			source: vectorSource,
   334  			style: styleFunction,
   335  		});
   336  
   337  		var map = new ol.Map({
   338  			layers: [
   339  				new ol.layer.Tile({
   340  					source: new ol.source.OSM()
   341  				}),
   342  				vectorLayer
   343  			],
   344  			target: 'map',
   345  			controls: ol.control.defaults({
   346  				attributionOptions: {
   347  					collapsible: false
   348  				}
   349  			}),
   350  			view: new ol.View({
   351  				zoom: -10
   352  			})
   353  		});
   354  		map.getView().fit(vectorLayer.getSource().getExtent(), map.getSize());
   355  		map.getView().setZoom(15);
   356  
   357  		var overlay = new ol.Overlay({
   358  			element: document.getElementById('popup-container'),
   359  			positioning: 'bottom-center',
   360  			offset: [0, -10]
   361  		});
   362  		map.addOverlay(overlay);
   363  	</script>`