Selections of geo objects
There are various actions you can perform when working with an interactive map with geo objects. For example, add to the map, change properties or options, assign an event handler, and so on. These are basic operations, and a corresponding function is defined for each of them in the API.
However, a developer often faces more difficult tasks. For example, you need to find geo objects that are located north of some geographical region (house, street, etc.). Or you need to find out whether a geo object falls into the geographical region of another object. The implementation of such tasks using standard API functions can lead to a significant expansion of the program code.
To simplify such tasks, the API has a built-in set of helper methods. These methods are wrappers for standard API functions. When using helper methods, you do not need to implement operations such as searching geo objects, detecting their position relative to each other, and many other operations.
As an example, the table below shows two ways of completing the same task.
Task: Make geo objects red if they fall within a draggable circle. But make all other geo objects blue (see the example in the sandbox).
Standard implementation |
Implementation using helper methods |
|
|
As seen in the example, helper methods can significantly simplify the programming code.
Helper methods are defined in the GeoQueryResult class. The GeoQueryResult
object is called a geo object selection and consists of data storage with a special structure. The geo objects that actions will be performed on must first be added to this object. This can be any type of geo objects: placemarks, circles, rectangles, collections of them, and so on. However, they do not have to be placed on the map.
To create a GeoQueryResult
selection, use the geoQuery function. It is passed the data source — geo objects that the selection will be based on.
var circle = new ymaps.Circle([[30, 42 ], 5000]);
//Adding a circle to the map
myMap.geoObjects.add(circle);
// Making the data source.
var objects = [
new ymaps.Placemark([34, 56]),
new ymaps.Rectangle([[34, 56], [36, 57]]),
circle
],
// Making the selection.
storage = ymaps.geoQuery(objects);
// All the map's geo objects are passed to the selection as the data source
var storage = ymaps.geoQuery(myMap.geoObjects);
The geoQuery
function can also form a selection of geo objects based on an asynchronous data source. For example, the data source may be the resulting data that will be received from the server. Since processing the request and response takes some time, geoQuery
will wait for the source to be ready before making the selection:
// When the server returns the result, geoQuery will process data and construct the selection based on it.
ymaps.geoQuery(ymaps.geocode('Saint Petersburg'));
The geoQuery
function returns the GeoQueryResult
selection that was formed. Now various actions can be performed with its objects, using helper methods: add to the map, set properties or options, and so on. Various filters can also be applied to this selection to make new selections based on it.
The set of available methods for performing various operations with a selection and its geo objects is shown below:
1. Methods that perform operations on the selection
The selection is an ordered array of geo objects that have been selected by some criteria. As with normal arrays, various actions can be performed with the selection, such as adding or removing objects, sorting, putting its items in reverse order, and so on. The following methods are intended for use with an array of selected objects:
add
Adds new objects to the selection. It does not change the original GeoQueryResult
selection, but creates a new one that contains the resulting set of geo objects.
var placemark = new ymaps.Placemark([34, 56]);
myGeoQueryResult.add(placemark);
For more information about the method, see the Reference guide.
getLength
Returns the number of items in the selection.
var result = ymaps.geoQuery(myMap.geoObject).searchIntersect(myPolygon);
alert('The number of geo objects that intersect with the polygon: ' + result.getLength());
For more information about the method, see the Reference guide.
remove
Removes objects from the selection. It does not change the original selection, but creates a new one that contains the resulting set of geo objects.
var objects = [
new ymaps.Placemark([34, 56]),
new ymaps.Rectangle([[34, 56], [36, 57]])
],
result = ymaps.geoQuery(objects);
// Note that a different GeoQueryResult object will be obtained in the result, while the old one remains unchanged.
var newResult = result.remove(objects[1]);
For more information about the method, see the Reference guide.
reverse
Reverses the order of the items in the selection. Returns a new selection.
var result = ymaps.geoQuery(myMap.geoObjects).sort('x'),
reversedResult = result.reverse();
For more information about the method, see the Reference guide.
slice
Returns a slice of the selection.
var result = ymaps.geoQuery(map.geoObjects).slice(0, 10);
alert('Number of items in the new selection:' + result.getLength());
For more information about the method, see the Reference guide.
sort
Sorts the selection by the given parameter.
var result = ymaps.geoQuery(myMap.geoObjects);
result.sort('lat').sort('x');
For more information about the method, see the Reference guide.
sortByDistance
Creates a new selection of items that are sorted by their distance from the specified object.
var result = ymaps.geoQuery(objects).addToMap(myMap),
polyline = new ymaps.Polyline([[35, 65], [35, 66], [34, 62], [34, 63]]);
myMap.geoObjects.add(polyline);
var sortedByPolyline = result.sortByDistance(polyline);
For more information about the method, see the Reference guide.
2. Methods for accessing a selection item
The following methods are used for accessing a selection item:
each
Passes through the selection items.
ymaps.geoQuery(placemarks).searchIntersect(myMap).each(function(pm) {
if (pm.options.get('preset') == 'islands#redIcon') {
myMap.geoObjects.remove(pm);
}
});
For more information about the method, see the Reference guide.
get
Returns a selection item by index.
var result = ymaps.geoQuery(placemarks).sort('lat'),
// Southernmost object.
southObject = result.get(0),
// Northernmost object.
northObject = result.get(result.getLength() - 1);
For more information about the method, see the Reference guide.
getIterator
Returns an iterator for selection items.
// Searching for elements that match the click coordinates.
myMap.events.add('click', function (event) {
var iterator = ymaps.geoQuery(myMap.geoObjects)
.searchContaining(event.getCoordinates())
.getIterator(),
obj;
while ((obj = iterator.getNext()) != iterator.STOP_ITERATION) {
// Performing the necessary actions on a geo object.
}
});
For more information about the method, see the Reference guide.
indexOf
Returns the index of an item in the selection. If the item was not found, it returns -1.
// Sorting the selection by the "name" field.
var result = ymaps.geoQuery(polygons).sort('properties.name');
alert('New position of the first item: ' + result.indexOf(polygons[0]));
For more information about the method, see the Reference guide.
map
Calls the callback
method for all the selection items and forms a new selection based on the results received.
// Adding only circle objects to the map.
var circlesResult = ymaps.geoQuery(objects).search('geometry.type="Circle"').addToMap(myMap),
// We'll also add placemarks that mark the circle centers.
centers = circlesResult.map(function (object) {
return new ymaps.Placemark(object.geometry.getCenter());
}).addToMap(myMap);
For more information about the method, see the Reference guide.
3. Methods for processing asynchronous operations
Operations with selections can be performed asynchronously. Asynchronous mode usually occurs when data is exchanged with the server in one of the functions. Since getting the data takes some time, all the subsequent functions that are interacting with the selection must wait for the results to be ready.
Asynchronous interaction is implemented using promise objects. The following diagram shows how this type of interaction works.
All the functions in the chain are called synchronously. This means that the interpreter calls them sequentially, in a single thread. The process of filling the selection is asynchronous. If the data for forming the selection are not ready when a function is called, this function creates an empty GeoQueryResult
object. The promise
object that was passed by the previously called function is now passed to the empty object's constructor. Execution of the promise
object means that the data is ready and the selection can be formed.
On the picture, the geocode
function, which is waiting for a response from the server, creates the promise
object, which is fulfilled when the server returns the data. The next geoQuery
function subscribes to promise1
and starts filling the selection only when this promise object is fulfilled. Similarly, a new promise3
object is created, and the next add
function will subscribe to it.
Alert
Functions that do not return the GeoQueryResult
object (such as getLength()
) are executed synchronously, meaning they do not wait for data to be ready before starting:
var result = ymaps.geoQuery(ymaps.geocode('Lena river')).getLength();
alert(result); // result = 0
In order for these functions to be executed asynchronously, their call of the then
function must be passed as a callback
:
var result = ymaps.geoQuery(ymaps.geocode('Lena river'));
result.then(function () {
alert('Number of objects found: ' + result.getLength());
}, function () {
alert('Error occurred.');
});
For more information about the method, see the Reference guide.
To debug an asynchronous operation, use the isReady()
method, which returns a flag for the result readiness:
var result = ymaps.geoQuery(ymaps.geocode('Ivanovo'));
if (!result.isReady()) {
result.then(function () {
// Processing data.
});
} else {
// Processing data.
}
For more information about the method, see the Reference guide.
4. Methods for group processing of selection items
Various actions can be performed with the geo objects in a selection: add to the map, change properties and options, and so on. A list of methods for working with a group of geo objects is provided below:
addEvents
Assigns event handlers to all the items in the selection.
ymaps.geoQuery(map.geoObjects).search('geometry.type="Circle"').addEvents('click', function () {
alert('You clicked a circle!');
});
For more information about the method, see the Reference guide.
addTo
Adds selection items to the specified collection of geo objects.
// Showing objects in the northern hemisphere on the map.
var result1 = ymaps.geoQuery(placemarks).search('lat > 0').addTo(myMap.geoObjects);
For more information about the method, see the Reference guide.
addToMap
Adds objects in the selection to the map.
// Showing objects in the northern hemisphere on the map.
var result1 = ymaps.geoQuery(placemarks).search('lat > 0').addToMap(myMap);
For more information about the method, see the Reference guide.
clusterize
Creates a clusterer and adds objects from the selection to it. If the selection data is not ready yet, it will be added to the clusterer immediately after processing, but the returned clusterer will be empty at first.
// Selecting only point objects and adding them to the clusterer.
var clusterer = ymaps.geoQuery(objects).search('geometry.type="Point"').clusterize();
myMap.geoObjects.add(clusterer);
For more information about the method, see the Reference guide.
removeEvents
Deletes the subscription to events from objects.
Alert
In order to unsubscribe correctly, the arguments passed must be exactly the same as the ones for subscribing via the addEvents
method.
var callback = function () {
alert('You clicked a circle!);
};
ymaps.geoQuery(map.geoObjects).search('geometry.type="Circle"').addEvents('click', callback);
// ...
ymaps.geoQuery(map.geoObjects).search('geometry.type="Circle"').removeEvents('click', callback);
For more information about the method, see the Reference guide.
removeFrom
Removes selection objects from the specified collection of geo objects.
// Showing all objects on the map.
var result1 = ymaps.geoQuery(placemarks).addTo(myMap.geoObjects),
// Then hiding objects in the northern hemisphere.
result2 = result1.search('lat > 0').removeFrom(myMap.geoObjects);
For more information about the method, see the Reference guide.
removeFromMap
Removes selection objects from the map.
// Showing all objects on the map.
var result1 = ymaps.geoQuery(placemarks).addToMap(myMap),
// Then hiding objects in the northern hemisphere.
result2 = result1.search('lat > 0').removeFromMap(myMap);
For more information about the method, see the Reference guide.
setOptions
Sets the value of options for all the objects in the selection.
var result = ymaps.geoQuery(placemarks);
// Making items visible that fall within a rectangular region.
result.searchIntersect(myBounds).setOptions('visible', true);.
For more information about the method, see the Reference guide.
setProperties
Sets the value of the properties
field for all the objects in the selection.
var result = ymaps.geoQuery(objects);
// Marking elements that fall inside the area.
result.searchIntersect(myBounds1).setProperties('intersectBounds', true);
result.searchIntersect(myBounds2).setProperties('intersectBounds', true);
// ...
result.search('properties.intersectBounds = true').addToMap(myMap);
For more information about the method, see the Reference guide.
unsetOptions
Resets the value of options for all the objects in the selection.
result.unsetOptions('visible');
For more information about the method, see the Reference guide.
unsetProperties
Resets the value of the properties
field for all the items in the selection.
var result = ymaps.geoQuery(objects);
// Marking items that fall inside the first area, but do not fall inside the second one.
result.searchIntersect(myBounds1).setProperties('intersectBounds', true);
result.searchIntersect(myBounds2).unsetProperties('intersectBounds', true);
// ...
result.search('properties.intersectBounds = true').addToMap(myMap);
For more information about the method, see the Reference guide.
5. Methods that perform search on a selection
intersect
Creates a new selection containing common items for two different selections.
var result = ymaps.geoQuery(placemarks),
greenObjects = result.search('properties.color=green'),
roundObjects = result.search('properties.shape=round'),
greenRoundObjects = greenObjects.intersect(roundObjects);
alert('Number of round green objects: ' + greenRoundObjects.getLength());
For more information about the method, see the Reference guide.
search
Searches for selection objects that meet the specified conditions.
var result = ymaps.geoQuery(myMap.geoObjects);
// Searching for objects with a specific type of geometry. The value is set in quotation marks, since it is a string.
result.search('geometry.type = "Point"')
// Searching by coordinates.
.search('geometry.coordinates.0 > 100')
For more information about the method, see the Reference guide.
searchContaining
Creates a new selection from objects containing the specified geo object.
Alert
For correct calculations, all geo objects must be added to the map. If geo objects do not need to be displayed, set their "visible" option to visible: false
.
var result = ymaps.geoQuery(objects).addToMap(myMap),
polygon = new ymaps.Polygon([[[35, 65], [35, 66], [34, 62], [34, 63], [35, 65]]]);
myMap.geoObjects.add(polygon);
var objectsContainingPolygon = result.searchContaining(polygon);
For more information about the method, see the Reference guide.
searchInside
Creates a new selection from objects that are completely inside the specified object.
Alert
For correct calculations, the geo objects must be added to the map. If geo objects do not need to be displayed, set their "visible" option to visible: false
.
var result = ymaps.geoQuery(objects).addToMap(myMap),
polygon = new ymaps.Polygon([[[35, 65], [35, 66], [34, 62], [34, 63], [35, 65]]]);
myMap.geoObjects.add(polygon);
var objectsInsidePolygon = result.searchInside(polygon);
For more information about the method, see the Reference guide.
searchIntersect
Creates a new selection from the selection objects that intersect the specified object.
Alert
For correct calculations, the geo objects must be added to the map. If geo objects do not need to be displayed, set their "visible" option to visible: false
.
var result = ymaps.geoQuery(objects).addToMap(myMap),
polygon = new ymaps.Polygon([[[35, 65], [35, 66], [34, 62], [34, 63], [35, 65]]]);
myMap.geoObjects.add(polygon);
var objectsIntersectPolygon = result.searchIntersect(polygon);
For more information about the method, see the Reference guide.
6. Methods for getting geometric parameters of a selection
applyBoundsToMap
Allows setting the map viewport so that all the objects in the selection are visible.
var result = ymaps.geoQuery(objects).applyBoundsToMap(myMap);
alert('Map viewport changed.');
For more information about the method, see the Reference guide.
getBounds
Returns the geographical coordinates of the area that includes all the result objects.
// Setting the map center and zoom so that the entire result is displayed.
myMap.setBounds(myResult.getBounds());
{% cut "getCenter" %}
Returns the coordinates of the center of the area that spans the objects.
// Moving the map center to the center of the area that covers the objects.
myMap.setCenter(ymaps.geoQuery(objects).getCenter());
getCentralObject
Returns the geo object that is closes to the center of the map viewport.
// Opening a balloon for the geo object that is closest to the center of the map viewport.
ymaps.geoQuery(objects).getCentralObject(myMap).balloon.open();
getClosestTo
Returns the selection object that is closest to the one specified. If an object that is already in the selection is given as input, it returns a different object from the selection that is closest to the one specified.
Alert
For correct calculations, the geo objects must be added to the map. If geo objects do not need to be displayed, set their "visible" option to visible: false
.
var result = ymaps.geoQuery(objects).addToMap(myMap),
polyline = new ymaps.Polyline([[35, 65], [35, 66], [34, 62], [34, 63]]);
myMap.geoObjects.add(polyline);
var closestObject = result.getClosestTo(polyline);
For more information about the method, see the Reference guide.
getExtreme
Returns the maximum and minimum coordinate values among the coordinates of objects in the selection.
alert('Northernmost coordinate: ', ymaps.geoQuery(myMap.geoObjects).getExtreme('top'));
For more information about the method, see the Reference guide.
getExtremeObject
Returns the object with the minimum or maximum coordinates among the coordinates of objects in the selection.
// Opening a balloon on the northernmost object.
var topObject = ymaps.geoQuery(myMap.geoObjects).getExtremeObject('top');
topObject.balloon.open();
For more information about the method, see the Reference guide.
getGlobalPixelBounds
Returns global pixel coordinates for the area that spans the selection objects (for the current map zoom value).
var result = ymaps.geoQuery(placemarks).search('properties.type="shop"').getGlobalPixelBounds(myMap);
if (Math.abs(result[0][0] - result[1][0]) > myMap.container.getSize()[0]) {
alert('Objects are too wide to fit on the map!');
}
For more information about the method, see the Reference guide.
getGlobalPixelCenter
For the current zoom level, returns the global pixel coordinates of the center of the area that spans the selection objects.
// Calculating the tile number that contains the center of the area that spans the result.
var globalPixelCenter = ymaps.geoQuery(objects).getGlobalPixelCenter(myMap),
tileNumber = [
Math.floor(globalPixelCenter[0] / 256),
Math.floor(globalPixelCenter[1] / 256)
];
alert('Number of the center tile: ' + tileNumber[0] + ' ' + tileNumber[1]);
For more information about the method, see the Reference guide.
Note
In the Sandbox, you can explore examples of working with a selection of geo objects.