polygon around polyline with radius? - ios

I have the problem with drawing polygon around polyline.
I have coordinates of every polyline's point and I want to get coordinates of polygon around this polyline.
I use MapBox's map.
Any ideas? I didn't find solutions.
Something, that seems like this.
I need to get coordinates for drawing polygon around line.

I found solution, guys! That was really diffucult :D
According to last hint about Turf :)
I found pod "SwiftTurf"
var coordsPointer = UnsafeMutablePointer<CLLocationCoordinate2D>.allocate(capacity: Int(polyline.pointCount))
polyline.getCoordinates(coordsPointer, range: NSMakeRange(0, Int(polyline.pointCount)))
// save coords
var lineCoords: [CLLocationCoordinate2D] = []
for i in 0..<polyline.pointCount {
lineCoords.append(coordsPointer[Int(i)])
}
let lineString:LineString = LineString(geometry: lineCoords)
let bufferLineString = SwiftTurf.buffer(lineString, distance: width, units: .Meters)
let outer = bufferLineString!.geometry![0]
let interiors = bufferLineString?.geometry![1..<bufferLineString!.geometry.count].map({ coords in
return MGLPolygon(coordinates: coords, count: UInt(coords.count))
})
// This polygon is solution
self.currentBufferPolygon = MGLPolygon(coordinates: outer, count: UInt(outer.count), interiorPolygons: interiors)
mapView.addAnnotation(self.currentBufferPolygon!)
U can find more info on github in the pod's repo :) Good luck!

If you're looking to draw a polygon around a polyline in the browser, I suggest using turf.js. Turf's buffer method should work nicely for this exact case.
Here's an example on a Mapbox GL JS map
var line = {
"type": "Feature",
"properties": {},
"geometry": {
"type": "LineString",
"coordinates": [
[-122.40447521209718,
37.79367718768535
],
[-122.40803718566895,
37.79171022624846
],
[-122.40769386291502,
37.79096412372944
],
[-122.40662097930908,
37.789641468930114
],
[-122.40941047668457,
37.789675383451495
],
[-122.40992546081543,
37.78875968591083
],
[-122.40962505340575,
37.78791180770003
]
]
}
};
mapboxgl.accessToken = 'pk.eyJ1IjoibWFwc2FtIiwiYSI6ImNqNzI4ODR4djBkZmczMnJzZjg3eXZhcDgifQ.5xM2OR_RvuO6YvirBVeiOg';
var map = new mapboxgl.Map({
container: 'map',
style: 'mapbox://styles/mapbox/light-v9',
zoom: 15,
center: [-122.4067, 37.7899]
});
map.on('load', function() {
map.addLayer({
"id": "route",
"type": "line",
"source": {
"type": "geojson",
"data": line
}
});
var polygon = turf.buffer(line, 50, 'meters');
map.addLayer({
"id": "poly",
"type": "fill",
"source": {
"type": "geojson",
"data": polygon
},
"layout": {},
"paint": {
"fill-color": '#d9d838',
"fill-opacity": 0.3
}
});
});
body {
margin: 0;
padding: 0;
}
#map {
position: absolute;
top: 0;
bottom: 0;
width: 100%;
}
<html>
<head>
<meta charset='utf-8' />
<title></title>
<meta name='viewport' content='initial-scale=1,maximum-scale=1,user-scalable=no' />
<script src='https://api.tiles.mapbox.com/mapbox-gl-js/v0.39.1/mapbox-gl.js'></script>
<link href='https://api.tiles.mapbox.com/mapbox-gl-js/v0.39.1/mapbox-gl.css' rel='stylesheet' />
<script src='https://npmcdn.com/#turf/turf/turf.min.js'></script>
</head>
<body>
<div id='map'></div>
</body>
</html>

Related

set marker visibility from geoJson source

I'm using a geojson that contains cities in italy, where I have "data" to read; data is stored in the properties fields. I can add even more data, for example we are thinking about adding the density of people for each city, to make cities more or less relevant, to be translated in which city is shown before on the maps.
The geojson:
{
type: "geojson",
data: {
type: "FeatureCollection",
features: [
{
type: "Feature",
geometry: {
type: "Point",
coordinates: [11.433, 46.883],
},
properties: {
title: "Vipiteno",
/* etc */
},
},
{
type: "Feature",
geometry: {
type: "Point",
coordinates: [11.326, 46.46],
},
properties: {
title: "Bolzano",
/* etc */
},
},
],
},
}
On my page I add the geojson to the map by using this function:
map.on("load", function () {
// Add an image to use as a custom marker
map.loadImage("img", function (error, image) {
if (error) throw error;
map.addImage("custom-marker", image);
// Add a GeoJSON source with 2 points
map.addSource("points", geoJson);
map.addLayer({
id: "points",
type: "symbol",
source: "points",
layout: {
"icon-image": "custom-marker",
// get the title name from the source's "title" property
"text-field": ["get", "title"],
"text-font": ["Open Sans Semibold", "Arial Unicode MS Bold"],
"text-offset": [0, 1.25],
"text-anchor": "top",
},
});
});
});
So how can I control which markers are shown at first load, and then showing more more points when the user zooms in?
Right now just a few are rendered at starting zoom level, but there is no control on which, and small cities are rendered before capitals (for example).
How can I override this?
You can override this by setting the zoom / adding a zoom expression for dynamic visibility changes. The below Mapbox example does something similar. By using a dynamic zoom expression the cirle layer opacity is gradually changed. You could do the same for your layer. Thereby you can control which layer is visible at which zoom with which specific opacity. Please see this example:
https://docs.mapbox.com/help/tutorials/mapbox-gl-js-expressions/#add-a-zoom-expression
(To run, exchange "YOUR ACCESS TOKEN")
<!DOCTYPE html>
<html>
<head>
<meta charset='utf-8' />
<title>Minneapolis Landmarks</title>
<meta name='viewport' content='initial-scale=1,maximum-scale=1,user-scalable=no' />
<script src='https://api.tiles.mapbox.com/mapbox-gl-js/v2.0.1/mapbox-gl.js'></script>
<link href='https://api.tiles.mapbox.com/mapbox-gl-js/v2.0.1/mapbox-gl.css' rel='stylesheet' />
<style>
body {
margin: 0;
padding: 0;
}
#map {
position: absolute;
top: 0;
bottom: 0;
width: 100%;
}
</style>
</head>
<body>
<div id='map'></div>
<script>
mapboxgl.accessToken = 'YOUR ACCESS TOKEN';
var map = new mapboxgl.Map({
container: 'map', // container id
style: 'mapbox://styles/mapbox/light-v10', // stylesheet location
center: [-93.261, 44.971], // starting position [lng, lat]
zoom: 10.5 // starting zoom
});
map.on('load', function() {
map.addLayer({
id: 'historical-places',
type: 'circle',
source: {
type: 'vector',
url: 'mapbox://your-tileset-id-here'
},
'source-layer': 'your-source-layer-here',
paint: {
'circle-radius': [
'interpolate', ['linear'], ['zoom'],
10, ['/', ['-', 2017, ['number', ['get', 'Constructi'], 2017]], 30],
13, ['/', ['-', 2017, ['number', ['get', 'Constructi'], 2017]], 10],
],
'circle-opacity': 0.8,
'circle-color': 'rgb(171, 72, 33)'
}
});
});
</script>
</body>
</html>

Snazzy Maps in Rails Application

I set up a nice map in my rails application. Everything is working fine but I cannot style the map with SnazzyMaps.
Here is my map.js file:
import GMaps from 'gmaps/gmaps.js';
const mapElement = document.getElementById('map');
if (mapElement) { // don't try to build a map if there's no div#map to inject in
const map = new GMaps({ el: '#map', lat: 0, lng: 0 });
const markers = JSON.parse(mapElement.dataset.markers);
const mapMarkers = map.addMarkers(markers);
mapMarkers.forEach((marker, index) => {
marker.addListener('click', () => {
// map.setCenter(markers[index]);
markers[index].infoWindow.open(map, marker);
})
});
if (markers.length === 0) {
map.setZoom(2);
} else if (markers.length === 1) {
map.setCenter(markers[0].lat, markers[0].lng);
map.setZoom(14);
} else {
map.fitLatLngBounds(markers);
}
}
import { autocomplete } from '../components/autocomplete';
// [...]
autocomplete();
On SnazzyMaps they give the following example. My question is, where shall I insert which part of this code in my own file. Been trying it for a while now but cannot make it work. Here is SnazzyMaps example:
<!DOCTYPE html>
<html>
<head>
<title>Snazzy Maps Super Simple Example</title>
<style type="text/css">
/* Set a size for our map container, the Google Map will take up 100% of this container */
#map {
width: 750px;
height: 500px;
}
</style>
<!--
You need to include this script tag on any page that has a Google Map.
The following script tag will work when opening this example locally on your computer.
But if you use this on a localhost server or a live website you will need to include an API key.
Sign up for one here (it's free for small usage):
https://developers.google.com/maps/documentation/javascript/tutorial#api_key
After you sign up, use the following script tag with YOUR_GOOGLE_API_KEY replaced with your actual key.
<script type="text/javascript" src="https://maps.googleapis.com/maps/api/js?key=YOUR_GOOGLE_API_KEY"></script>
-->
<script type="text/javascript" src="https://maps.googleapis.com/maps/api/js"></script>
<script type="text/javascript">
// When the window has finished loading create our google map below
google.maps.event.addDomListener(window, 'load', init);
function init() {
// Basic options for a simple Google Map
// For more options see: https://developers.google.com/maps/documentation/javascript/reference#MapOptions
var mapOptions = {
// How zoomed in you want the map to start at (always required)
zoom: 11,
// The latitude and longitude to center the map (always required)
center: new google.maps.LatLng(40.6700, -73.9400), // New York
// How you would like to style the map.
// This is where you would paste any style found on Snazzy Maps.
styles: [{"featureType":"all","elementType":"geometry.fill","stylers":[{"weight":"2.00"}]},{"featureType":"all","elementType":"geometry.stroke","stylers":[{"color":"#9c9c9c"}]},{"featureType":"all","elementType":"labels.text","stylers":[{"visibility":"on"}]},{"featureType":"landscape","elementType":"all","stylers":[{"color":"#f2f2f2"}]},{"featureType":"landscape","elementType":"geometry.fill","stylers":[{"color":"#ffffff"}]},{"featureType":"landscape.man_made","elementType":"geometry.fill","stylers":[{"color":"#ffffff"}]},{"featureType":"poi","elementType":"all","stylers":[{"visibility":"off"}]},{"featureType":"road","elementType":"all","stylers":[{"saturation":-100},{"lightness":45}]},{"featureType":"road","elementType":"geometry.fill","stylers":[{"color":"#eeeeee"}]},{"featureType":"road","elementType":"labels.text.fill","stylers":[{"color":"#7b7b7b"}]},{"featureType":"road","elementType":"labels.text.stroke","stylers":[{"color":"#ffffff"}]},{"featureType":"road.highway","elementType":"all","stylers":[{"visibility":"simplified"}]},{"featureType":"road.arterial","elementType":"labels.icon","stylers":[{"visibility":"off"}]},{"featureType":"transit","elementType":"all","stylers":[{"visibility":"off"}]},{"featureType":"water","elementType":"all","stylers":[{"color":"#46bcec"},{"visibility":"on"}]},{"featureType":"water","elementType":"geometry.fill","stylers":[{"color":"#c8d7d4"}]},{"featureType":"water","elementType":"labels.text.fill","stylers":[{"color":"#070707"}]},{"featureType":"water","elementType":"labels.text.stroke","stylers":[{"color":"#ffffff"}]}]
};
// Get the HTML DOM element that will contain your map
// We are using a div with id="map" seen below in the <body>
var mapElement = document.getElementById('map');
// Create the Google Map using our element and options defined above
var map = new google.maps.Map(mapElement, mapOptions);
// Let's also add a marker while we're at it
var marker = new google.maps.Marker({
position: new google.maps.LatLng(40.6700, -73.9400),
map: map,
title: 'Snazzy!'
});
}
</script>
</head>
<body>
<h1>Snazzy Maps Super Simple Example</h1>
<h2>WY</h2>
<!-- The element that will contain our Google Map. This is used in both the Javascript and CSS above. -->
<div id="map"></div>
</body>
</html>
To set the style using Gmaps library, you need to define the styles and then set it to the current map as below:
const map = new GMaps({ el: '#map', lat: 0, lng: 0 });
var styles = [
{
stylers: [
{ hue: "#00ffe6" },
{ saturation: -20 }
]
}, {
featureType: "road",
elementType: "geometry",
stylers: [
{ lightness: 100 },
{ visibility: "simplified" }
]
}, {
featureType: "road",
elementType: "labels",
stylers: [
{ visibility: "off" }
]
}
];
map.addStyle({
styledMapName:"Styled Map",
styles: styles,
mapTypeId: "map_style"
});
map.setStyle("map_style");
Reference:
https://github.com/hpneo/gmaps/blob/master/examples/styled_maps.html

How to show the marker upfront in openlayers3 while drawing the polyline

I am drawing the polylines on the map and displaying few marker as well which is working fine but when the polyline is drawn marker is above the line
I wanted to know like can the shown the marker upfront when i draw the polyline
<!DOCTYPE html>
<html>
<head lang="en">
<meta charset="UTF-8">
<title></title>
<!-- <link rel="stylesheet" href="http://openlayers.org/en/v3.2.1/css/ol.css" type="text/css">-->
</head>
<body>
<div id="map" class="map"></div>
<link rel="stylesheet" href="http://openlayers.org/en/v3.12.1/css/ol.css" type="text/css">
<script src="http://openlayers.org/en/v3.12.1/build/ol.js"></script>
<script>
var map;
var vectorLayer;
var extentToZoom;
var geojsonObject;
function drawPolyline(geoObject){
var image = new ol.style.Circle({
radius: 5,
fill: null,
stroke: new ol.style.Stroke({color: 'red', width: 1})
});
var styles = {
'greenRoute': new ol.style.Style({
stroke: new ol.style.Stroke({
color: 'green',
width: 3
})
}),
'redRoute': new ol.style.Style({
stroke: new ol.style.Stroke({
color: 'red',
width: 3
})
})
};
var styleFunction = function(feature, resolution) {
return styles[feature.get("fName")];
};
geojsonObject =geoObject;
var routeGeom = new ol.format.Polyline(
{
factor: 1e6
}).readGeometry(geojsonObject.route_geometry, {
dataProjection: 'EPSG:4326',
featureProjection: 'EPSG:3857'
});
var colourRoute=["greenRoute","redRoute"]
var routeFeature = new ol.Feature({
geometry:routeGeom,
fName: colourRoute[Math.floor(Math.random()*colourRoute.length)]
})
console.log("color route"+colourRoute[Math.floor(Math.random()*colourRoute.length)]);
extentToZoom = routeGeom.getExtent();
var vectorSource = new ol.source.Vector({
features: [routeFeature]
});
//vectorSource.addFeature(new ol.Feature(new ol.geom.Circle([5e6, 7e6], 1e6)));
vectorLayer = new ol.layer.Vector({
source: vectorSource,
style: styleFunction
});
map.addLayer(vectorLayer);
}
function initMap(){
map = new ol.Map({
layers: [
new ol.layer.Tile({
source: new ol.source.XYZ({
urls : [" http://a.tile.openstreetmap.fr/openriverboatmap/{z}/{x}/{y}.png"," http://a.tile.openstreetmap.fr/openriverboatmap/{z}/{x}/{y}.png"," http://a.tile.openstreetmap.fr/openriverboatmap/{z}/{x}/{y}.png"]
})
})
],
target: 'map',
controls: ol.control.defaults({
attributionOptions: /** #type {olx.control.AttributionOptions} */ ({
collapsible: false
})
}),
view: new ol.View({
center: ol.proj.fromLonLat([103.986908, 1.353199]),
rotation: 68*Math.PI/180,
zoom: 18
})
});
}
function invokeAddMarker(){
var markerData = [
{
"title": 'point1',
"lat": 1.350664,
"lng": 103.985190,
"description": 'yyyy'
}, {
"title": 'point2',
"lat":1.353604,
"lng": 103.986395,
"description": 'zzz'
}, {
"title": 'point3',
"lat": 1.357227,
"lng": 103.9879999,
"description": 'uuu'
}
];
for(var i=0;i<markerData.length;i++){
addmarker(markerData[i].lat,markerData[i].lng);
}
}
function addmarker(lat,lng){
console.log("*****lat******"+lat);
console.log("*****lng******"+lng);
var iconFeature = new ol.Feature({
geometry: new ol.geom.Point(ol.proj.transform([lng,lat],'EPSG:4326', 'EPSG:3857')),
name: 'camera'
});
var iconStyle = new ol.style.Style({
image: new ol.style.Icon(({
anchor: [0.5, 46],
anchorXUnits: 'fraction',
anchorYUnits: 'pixels',
opacity: 0.75,
src: 'camera.png'
}))
});
iconFeature.setStyle(iconStyle);
vectorSource = new ol.source.Vector({
features: [iconFeature]
});
/*t clear the markers*/
/*vectorSource.clear();*/
vectorLayer = new ol.layer.Vector({
source: vectorSource
});
map.addLayer(vectorLayer);
map.on('click', function(evt) {
var feature = map.forEachFeatureAtPixel(evt.pixel,
function(feature, layer) {
return feature;
});
if (feature) {
alert("video comes here");
}
});
}
initMap();
invokeAddMarker();
geojsonObject ={"status":200,"hint_data":{"locations":["1DYUCf____89vE8AWwAAANkCAAAAAAAAcAAAAG_vKABaqAAATqcUAIO1MgYAAAEB","1DYUCf____89vE8AEAAAAHAAAADZAgAAAAAAAG_vKABaqAAAtZkUAPGvMgYBAAEB"],"checksum":4294707914},"route_name":["T3 Arrival Drive","T3 Arrival Drive"],"status_message":"Found route between points","route_geometry":"{srqAewyieEzrExuAtDhA","via_indices":[0,2],"route_instructions":[["10","T3 Arrival Drive",418,0,2,"418m","S",202,1,"N",22],["15","",0,2,0,"0m","N",0,"N",0]],"via_points":[[1.35355,103.986563],[1.350069,103.985137]],"found_alternative":false,"route_summary":{"total_distance":418,"total_time":65,"end_point":"T3 Arrival Drive","start_point":"T3 Arrival Drive"}};
drawPolyline(geojsonObject);
var geoobject2={"status":200,"hint_data":{"locations":["UiQkCf____-ljiMAEAAAABgAAAAAAAAAAAAAAP____-jqAAAt5gUAG2wMgYAAAEB","c8gaCf____8AAAAAMgAAALAAAAAAAAAAHQEAAOviEAajqAAAdqQUABy3MgYAAAEB"],"checksum":4089551480},"route_name":["East Coast Parkway (ECP)",""],"status_message":"Found route between points","route_geometry":"mjkqAyewieEsHuB_m#qWoYwJuDoDoAqBoFaJkCsD}H_Hai#{Pw`#iM","via_indices":[0,10],"route_instructions":[["10","East Coast Parkway (ECP)",18,0,2,"18m","N",21,1,"S",201],["1","",308,1,24,"307m","NE",28,1,"SW",208],["1","",65,9,5,"65m","NE",23,1,"SW",203],["15","",0,10,0,"0m","N",0,"N",0]],"via_points":[[1.349815,103.985261],[1.352822,103.986972]],"found_alternative":false,"route_summary":{"total_distance":391,"total_time":29,"end_point":"","start_point":"East Coast Parkway (ECP)"}};
drawPolyline(geoobject2);
var geoobject3={"status":200,"hint_data":{"locations":["NksUCf_____CwU8AzwAAABMBAAAAAAAAHQEAAG0BpwavqAAARaEUAOmxMgYAAAEB","R0sUCf_____CwU8AZgAAAPQAAADtAAAAKwIAAKQJ8QSvqAAAebIUAGy5MgYBAAEB"],"checksum":3361836982},"route_name":["T3 Departure Drive","T3 Departure Drive"],"status_message":"Found route between points","route_geometry":"isoqAq}wieEqUiHqpA__#cLkE}NgJyGaDiTmGemAk`#w`#kM","via_indices":[0,8],"route_instructions":[["10","T3 Departure Drive",535,0,81,"535m","N",22,1,"S",202],["15","",0,8,0,"0m","N",0,"N",0]],"via_points":[[1.352005,103.985641],[1.356409,103.987564]],"found_alternative":false,"route_summary":{"total_distance":535,"total_time":84,"end_point":"T3 Departure Drive","start_point":"T3 Departure Drive"}};
drawPolyline(geoobject3);
map.getView().fit(extentToZoom,map.getSize())
</script>
</body>
</html>
Here drawpoline() method will draw the lines using osrm service and invokeAddMarker() method has a array for which addmarker() method is invoke
i wanted shown something like above
All ol.style.Style settings have a zIndex parameter. You can use this to set the order of different styles.
http://openlayers.org/en/v3.12.1/apidoc/ol.style.Style.html

Select2 v4.0 make optgroups selectable

I'm using the latest version of select2 (4.0.0) and I can't find the option to make optgroups selectable.
An optgroup is used to group different options of the dropdown, as shown in their basic examples:
I need this optgoup to be selectable too! It was possible in 3.5.1 but it isn't the default setting in 4.0.0 anymore.
My Code Looks like this:
$(document).ready(function() {
$('#countrySelect').select2({
data: [{
text: "group",
"id": 1,
children: [{
"text": "Test 2",
"id": "2"
}, {
"text": "Test 3",
"id": "3",
"selected": true
}]
}]
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://select2.github.io/dist/js/select2.full.js"></script>
<link href="https://select2.github.io/dist/css/select2.min.css" rel="stylesheet" />
<select id="countrySelect" style="width: 380px;" placeholder="Select regions..."></select>
I manage to achieve this by using the templateResult property and attaching click events to the optgroups in this way:
$('#my-select').select2({
templateResult: function(item) {
if(typeof item.children != 'undefined') {
var s = $(item.element).find('option').length - $(item.element).find('option:selected').length;
// My optgroup element
var el = $('<span class="my_select2_optgroup'+(s ? '' : ' my_select2_optgroup_selected')+'">'+item.text+'</span>');
// Click event
el.click(function() {
// Select all optgroup child if there aren't, else deselect all
$('#my-select').find('optgroup[label="' + $(this).text() + '"] option').prop(
'selected',
$(item.element).find('option').length - $(item.element).find('option:selected').length
);
// Trigger change event + close dropdown
$('#my-select').change();
$('#my-select').select2('close');
});
// Hover events to properly manage display
el.mouseover(function() {
$('li.select2-results__option--highlighted').removeClass('select2-results__option--highlighted');
});
el.hover(function() {
el.addClass('my_select2_optgroup_hovered');
}, function() {
el.removeClass('my_select2_optgroup_hovered');
});
return el;
}
return item.text;
}
});
And the associated css:
.my_select2_optgroup_selected {
background-color: #ddd;
}
.my_select2_optgroup_hovered {
color: #FFF;
background-color: #5897fb !important;
cursor: pointer;
}
strong.select2-results__group {
padding: 0 !important;
}
.my_select2_optgroup {
display: block;
padding: 6px;
}
This was requested over on GitHub, but realistically it is not actually possible. It was previously possible with a <input />, but the switch to a <select> meant that we now explicitly disallow a selectable <optgroup>.
There is a technical barrier here that Select2 will likely never be able to tackle: A standard <optgroup> is not selectable in the browser. And because a data object with children is converted to an <optgroup> with a set of nested <option> elements, the problem applies in your case with the same issue.
The best possible solution is to have an <option> for selecting the group, like you would have with a standard select. Without an <option> tag, it's not possible to set the selected value to the group (as the value doesn't actually exist). Select2 even has a templateResult option (formatResult in 3.x) so you can style it as a group consistently across browsers.
Well, I came across this issue and I found that every time the select2 (Select2 4.0.5) opens it adds a span element before the closing body element. In addition, inside the span element adds a ul with the id: select2-X-results, where X is the select2 id.
So I found the following workaround (jsfiddle):
var countries = [{
"id": 1,
"text": "Greece",
"children": [{
"id": "Athens",
"text": "Athens"
}, {
"id": "Thessalonica",
"text": "Thessalonica"
}]
}, {
"id": 2,
"text": "Italy",
"children": [{
"id": "Milan",
"text": "Milan"
}, {
"id": "Rome",
"text": "Rome"
}]
}];
$('#selectcountry').select2({
placeholder: "Please select cities",
allowClear: true,
width: '100%',
data: countries
});
$('#selectcountry').on('select2:open', function(e) {
$('#select2-selectcountry-results').on('click', function(event) {
event.stopPropagation();
var data = $(event.target).html();
var selectedOptionGroup = data.toString().trim();
var groupchildren = [];
for (var i = 0; i < countries.length; i++) {
if (selectedOptionGroup.toString() === countries[i].text.toString()) {
for (var j = 0; j < countries[i].children.length; j++) {
groupchildren.push(countries[i].children[j].id);
}
}
}
var options = [];
options = $('#selectcountry').val();
if (options === null || options === '') {
options = [];
}
for (var i = 0; i < groupchildren.length; i++) {
var count = 0;
for (var j = 0; j < options.length; j++) {
if (options[j].toString() === groupchildren[i].toString()) {
count++;
break;
}
}
if (count === 0) {
options.push(groupchildren[i].toString());
}
}
$('#selectcountry').val(options);
$('#selectcountry').trigger('change'); // Notify any JS components that the value changed
$('#selectcountry').select2('close');
});
});
li.select2-results__option strong.select2-results__group:hover {
background-color: #ddd;
cursor: pointer;
}
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet"/>
<link href="https://cdnjs.cloudflare.com/ajax/libs/select2/4.0.5/css/select2.min.css" rel="stylesheet"/>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/select2/4.0.5/js/select2.full.min.js"></script>
<h1>Selectable optgroup using select2</h1>
<select id="selectcountry" name="country[]" class="form-control" multiple style="width: 100%"></select>
Had the same problem today. This is certainly not my nicest solution, but beggars can't be choosers:
$(document).on('click', '.select2-results__group', function(event) {
let select2El = $('#mySelect2');
var setValues = [];
//Add existing Selection
var selectedValues = select2El.select2('data');
for ( var i = 0, l = selectedValues.length; i < l; i++ ) {
setValues.push(selectedValues[i].id);
}
//Add Group Selection
$(this).next('ul').find('li').each(function(){
let pieces = $(this).attr('data-select2-id').split('-');
setValues.push(pieces[pieces.length-1]);
});
select2El.val(setValues).trigger('change').select2("close");
});
$(document).ready(function() {
$('#countrySelect').select2({
data: [{
text: "group",
"id": 1,
children: [{
"text": "Test 2",
"id": "2"
}, {
"text": "Test 3",
"id": "3",
"selected": true
}]
}]
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://select2.github.io/dist/js/select2.full.js"></script>
<link href="https://select2.github.io/dist/css/select2.min.css" rel="stylesheet" />
<select id="countrySelect" style="width: 380px;" placeholder="Select regions..."></select>

How to make radius circle in Google Maps?

I would need to set up in our application a radius circle into Google Maps, something like
(pink radius circle).
In the best way I would need to specify how big in miles the radius will be. As our application is written in Ruby On Rails, I am thinking whether will be better to use just Javascript or a gem.
Thank you very much!
EDIT: Attempts:
var map;
var miles = 3;
function initialize() {
var mapOptions = new google.maps.Circle({
center: new google.maps.LatLng(51.476706,0),
radius: miles * 1609.344,
fillColor: "#ff69b4",
fillOpacity: 0.5,
strokeOpacity: 0.0,
strokeWeight: 0,
map: map
});
map = new google.maps.Map(document.getElementById('map_canvas'), mapOptions);
}
google.maps.event.addDomListener(window, 'load', initialize);
But the map is not inicialized.
Well it's very easy to add a circle to a map with the Maps API, see
https://developers.google.com/maps/documentation/javascript/reference?csw=1#Circle
And then you just need some JS to convert miles to metres. Multiply by 1609.344 in fact should do it. So something like this perhaps:
<!DOCTYPE html>
<html>
<head>
<title>Circle</title>
<meta name="viewport" content="initial-scale=1.0, user-scalable=no" />
<style type="text/css">
html { height: 100% }
body { height: 100%; margin: 0; padding: 0 }
#map { height: 480px; width:600px; }
</style>
<script type="text/javascript" src="http://maps.googleapis.com/maps/api/js"></script>
<script>
function initialize() {
var miles = 3;
var map = new google.maps.Map(document.getElementById("map"), {
zoom: 11,
center: new google.maps.LatLng(51.476706, 0),
mapTypeId: google.maps.MapTypeId.ROADMAP
});
var circle = new google.maps.Circle({
center: new google.maps.LatLng(51.476706, 0),
radius: miles * 1609.344,
fillColor: "#ff69b4",
fillOpacity: 0.5,
strokeOpacity: 0.0,
strokeWeight: 0,
map: map
});
}
google.maps.event.addDomListener(window, 'load', initialize);
</script>
</head>
<body>
<div id="map"></div>
</body>
</html>
(updated my answer for a fully working solution)

Resources