Skip to content

Commit

Permalink
[ADD] search coordinates
Browse files Browse the repository at this point in the history
  • Loading branch information
Viglino committed Jun 19, 2024
1 parent e819cae commit f5e7a09
Show file tree
Hide file tree
Showing 4 changed files with 292 additions and 18 deletions.
89 changes: 89 additions & 0 deletions examples/search/map.control.searchcoord.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
<!DOCTYPE html>
<html>
<head>
<!--
Copyright (c) 2017-2018 Jean-Marc VIGLINO,
released under CeCILL-B (french BSD like) licence: http://www.cecill.info/
-->
<title>ol-ext: Search by coordinates</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />

<meta name="description" content="Control to add a grid reference to a map." />
<meta name="keywords" content="ol3, control, search, BAN, french, places, autocomplete" />

<!-- FontAwesome -->
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css">

<!-- jQuery -->
<script type="text/javascript" src="https://code.jquery.com/jquery-1.11.0.min.js"></script>
<!-- IE 9 bug on ajax tranport -->
<!--[if lte IE 9]>
<script type='text/javascript' src='//cdnjs.cloudflare.com/ajax/libs/jquery-ajaxtransport-xdomainrequest/1.0.3/jquery.xdomainrequest.min.js'></script>
<![endif]-->

<!-- Openlayers -->
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/ol@latest/ol.css" />
<script type="text/javascript" src="https://cdn.jsdelivr.net/npm/ol@latest/dist/ol.js"></script>
<script src="https://cdn.polyfill.io/v2/polyfill.min.js?features=requestAnimationFrame,Element.prototype.classList,URL,Object.assign"></script>

<!-- ol-ext -->
<link rel="stylesheet" href="../../dist/ol-ext.css" />
<script type="text/javascript" src="../../dist/ol-ext.js"></script>
<!-- Pointer events polyfill for old browsers, see https://caniuse.com/#feat=pointer -->
<script src="https://unpkg.com/elm-pep"></script>

<link rel="stylesheet" href="../style.css"/>
<style>
</style>
</head>
<body >
<a href="https://github.com/Viglino/ol-ext" class="icss-github-corner"><i></i></a>

<a href="../../index.html">
<h1>ol-ext: Search by coordinates control</h1>
</a>

<div class="info">
<i>ol.control.SearchCoordinates</i> is a control to search place using coordinates</a>.
</div>

<!-- DIV pour la carte -->
<div id="map" style="width:600px; height:400px;"></div>

<div class="options">
<i>Use the search control to start a new search.</i>
</div>

<script type="text/javascript">
// Layers
var layers = [ new ol.layer.Tile({ source: new ol.source.OSM() }) ];

// The map
var map = new ol.Map({
target: 'map',
view: new ol.View({
zoom: 5,
center: [166326, 5992663]
}),
layers: layers
});

// Set the control grid reference
var search = new ol.control.SearchCoordinates({
// target: $('.options').get(0)
});
map.addControl (search);

// Select feature when click on the reference index
search.on('select', function(e){
// console.log(e);
map.getView().animate({
center:e.search.coordinate,
zoom: Math.max (map.getView().getZoom(),5)
});
});

</script>

</body>
</html>
37 changes: 27 additions & 10 deletions src/control/Search.css
Original file line number Diff line number Diff line change
Expand Up @@ -223,13 +223,16 @@
}

/* GPS */
.ol-searchgps input.search {
.ol-searchgps input.search,
.ol-searchcoord input.search {
display: none;
}
.ol-control.ol-searchgps > button:first-child {
.ol-control.ol-searchgps > button:first-child,
.ol-control.ol-searchcoord > button:first-child {
background-image: none;
}
.ol-control.ol-searchgps > button:first-child:before {
.ol-control.ol-searchgps > button:first-child:before,
.ol-control.ol-searchcoord > button:first-child:before {
content: "x/y";
position: unset;
display: block;
Expand All @@ -239,22 +242,32 @@
width: auto;
height: auto;
}
.ol-control.ol-searchgps > button:first-child:after {
.ol-control.ol-searchgps > button:first-child:after,
.ol-control.ol-searchcoord > button:first-child:after {
content: unset;
}
.ol-control.ol-searchgps .ol-latitude,
.ol-control.ol-searchgps .ol-longitude {
.ol-control.ol-searchgps .ol-longitude,
.ol-control.ol-searchcoord .ol-latitude,
.ol-control.ol-searchcoord .ol-longitude {
clear: both;
}
.ol-control.ol-searchgps .ol-latitude label,
.ol-control.ol-searchgps .ol-longitude label {
.ol-control.ol-searchgps .ol-longitude label,
.ol-control.ol-searchcoord .ol-latitude label,
.ol-control.ol-searchcoord .ol-longitude label {
width: 5.5em;
display: inline-block;
text-align: right;
transform: scaleX(.8);
margin: 0 -.8em 0 0;
transform-origin: 0 0;
}
.ol-control.ol-searchcoord .ol-latitude label,
.ol-control.ol-searchcoord .ol-longitude label {
width: 2em;
margin: 0;
}
.ol-control.ol-searchgps .ol-latitude input,
.ol-control.ol-searchgps .ol-longitude input {
max-width: 10em;
Expand Down Expand Up @@ -285,17 +298,20 @@
width: .5em;
text-align: left;
}
.ol-searchgps.ol-control.ol-collapsed button.ol-geoloc {
.ol-searchgps.ol-control.ol-collapsed button.ol-geoloc,
.ol-searchcoord.ol-control.ol-collapsed button.ol-geoloc {
display: none;
}
.ol-searchgps button.ol-geoloc {
.ol-searchgps button.ol-geoloc,
.ol-searchcoord button.ol-geoloc {
top: 0;
float: right;
margin-right: 3px;
background-image: none;
position: relative;
}
.ol-searchgps button.ol-geoloc:before {
.ol-searchgps button.ol-geoloc:before,
.ol-searchcoord button.ol-geoloc:before {
content:"";
position: absolute;
left: 50%;
Expand All @@ -306,7 +322,8 @@
border-radius: 50%;
transform: translate(-50%,-50%);
}
.ol-searchgps button.ol-geoloc:after {
.ol-searchgps button.ol-geoloc:after,
.ol-searchcoord button.ol-geoloc:after {
content:"";
position: absolute;
left: 50%;
Expand Down
168 changes: 168 additions & 0 deletions src/control/SearchCoordinates.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,168 @@
/* Copyright (c) 2019 Jean-Marc VIGLINO,
released under the CeCILL-B license (French BSD license)
(http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.txt).
*/

import {transform as ol_proj_transform} from 'ol/proj.js'
import {toStringHDMS as ol_coordinate_toStringHDMS} from 'ol/coordinate.js';
import ol_Geolocation from 'ol/Geolocation.js'

import ol_control_Search from './Search.js'
import ol_ext_element from '../util/element.js'

/**
* Search on GPS coordinate.
*
* @constructor
* @extends {ol_control_Search}
* @fires select
* @param {Object=} Control options.
* @param {ol/proj/ProjectionLike} options.projection
* @param {string} [options.className] control class name
* @param {Element | string | undefined} [options.target] Specify a target if you want the control to be rendered outside of the map's viewport.
* @param {string | undefined} [options.label="search"] Text label to use for the search button, default "search"
* @param {string | undefined} [options.labelGPS="Locate with GPS"] placeholder, default "Locate with GPS"
* @param {number | undefined} [options.typing=300] a delay on each typing to start searching (ms), default 300.
* @param {integer | undefined} [options.minLength=1] minimum length to start searching, default 1
* @param {integer | undefined} [options.maxItems=10] maximum number of items to display in the autocomplete list, default 10
*/
var ol_control_SearchCoordinates = class olcontrolSearchCoordinates extends ol_control_Search {
constructor(options) {
options = options || {};
options.className = (options.className || '') + ' ol-searchcoord';
options.placeholder = options.placeholder || 'x,y';

super(options);

// Projection
this.projection_ = options.projection || 'EPSG:3857'
// Geolocation
this.geolocation = new ol_Geolocation({
projection: "EPSG:4326",
trackingOptions: {
maximumAge: 10000,
enableHighAccuracy: true,
timeout: 600000
}
});
ol_ext_element.create('BUTTON', {
className: 'ol-geoloc',
title: options.labelGPS || 'Locate with GPS',
parent: this.element,
click: function () {
this.geolocation.setTracking(true);
}.bind(this)
});

this._createForm();

// Move list to the end
var ul = this.element.querySelector("ul.autocomplete");
this.element.appendChild(ul);
}
/** Set the projection
*
*/
setProjection(proj) {
if (this.projection_ !== proj) {
this.projection_ = proj;
this.clearHistory();
this.element.querySelectorAll('INPUT[type="number"]').forEach(function(i) {
i.value = '';
})
}
}
/** Create input form
* @private
*/
_createForm() {

// Value has change
var onchange = function (e) {
if (lon.value || lat.value) {
this._input.value = lon.value + ',' + lat.value;
} else {
this._input.value = '';
}
// Center on coords
this.search();
}.bind(this);

function createInput(className) {
var input = ol_ext_element.create('INPUT', {
className: className,
type: 'number',
step: 'any',
lang: 'en',
parent: div,
on: {
'change keyup': onchange
}
});
return input;
}

// X
var div = ol_ext_element.create('DIV', {
className: 'ol-longitude',
parent: this.element
});
ol_ext_element.create('LABEL', {
html: 'X',
parent: div
});
var lon = createInput('ol-decimal');

// Y
div = ol_ext_element.create('DIV', {
className: 'ol-latitude',
parent: this.element
});
ol_ext_element.create('LABEL', {
html: 'Y',
parent: div
});
var lat = createInput('ol-decimal');

// Focus on open
if (this.button) {
this.button.addEventListener("click", function () {
lon.focus();
});
}

// Change value on click
this.on('select', function (e) {
lon.value = e.search.gps[0];
lat.value = e.search.gps[1];
}.bind(this));

// Change value on geolocation
this.geolocation.on('change', function () {
this.geolocation.setTracking(false);
var coord = this.geolocation.getPosition();
coord = ol_proj_transform(coord, 'EPSG:4326', this.projection_)
console.log(coord)
lon.value = coord[0];
lat.value = coord[1];
this._triggerCustomEvent('keyup', lon);
}.bind(this));
}
/** Autocomplete function
* @param {string} s search string
* @return {Array<any>|false} an array of search solutions
* @api
*/
autocomplete(s) {
var result = [];
var c = s.split(',');
c[0] = Number(c[0]);
c[1] = Number(c[1]);
//
var coord = ol_proj_transform([c[0], c[1]], this.projection_, this.getMap().getView().getProjection());
result.push({ gps: c, coordinate: coord, name: s });
return result;
}
}

export default ol_control_SearchCoordinates
16 changes: 8 additions & 8 deletions src/control/SearchGPS.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,13 +17,13 @@ import ol_ext_element from '../util/element.js'
* @extends {ol_control_Search}
* @fires select
* @param {Object=} Control options.
* @param {string} options.className control class name
* @param {Element | string | undefined} options.target Specify a target if you want the control to be rendered outside of the map's viewport.
* @param {string | undefined} options.label Text label to use for the search button, default "search"
* @param {string | undefined} options.placeholder placeholder, default "Search..."
* @param {number | undefined} options.typing a delay on each typing to start searching (ms), default 300.
* @param {integer | undefined} options.minLength minimum length to start searching, default 1
* @param {integer | undefined} options.maxItems maximum number of items to display in the autocomplete list, default 10
* @param {string} [options.className] control class name
* @param {Element | string | undefined} [options.target] Specify a target if you want the control to be rendered outside of the map's viewport.
* @param {string | undefined} [options.label=search] Text label to use for the search button, default "search"
* @param {string | undefined} [options.labelGPS="Locate with GPS"] placeholder, default "Locate with GPS"
* @param {number | undefined} [options.typing=300] a delay on each typing to start searching (ms), default 300.
* @param {integer | undefined} [options.minLength=1] minimum length to start searching, default 1
* @param {integer | undefined} [options.maxItems=10] maximum number of items to display in the autocomplete list, default 10
*/
var ol_control_SearchGPS = class olcontrolSearchGPS extends ol_control_Search {
constructor(options) {
Expand All @@ -44,7 +44,7 @@ var ol_control_SearchGPS = class olcontrolSearchGPS extends ol_control_Search {
});
ol_ext_element.create('BUTTON', {
className: 'ol-geoloc',
title: 'Locate with GPS',
title: options.labelGPS || 'Locate with GPS',
parent: this.element,
click: function () {
this.geolocation.setTracking(true);
Expand Down

0 comments on commit f5e7a09

Please sign in to comment.