Store Locator
Show pins on map and catch user interaction with the map.
StoreLocator can manage multiple map engine instances such as google maps
and naver map
You can write your own map engine extending the
Map
interface and following method implementation viaPromise
Version
3.0.0
Installation
npm install --save ssh://stash.openmindonline.it:7999/oc/storelocator.git#3.0.0
Integration
All files are included in dist
folder
The entry-point file is
storelocator.js
and its main class is StoreLocator
let storeLocator = new StoreLocator(...);
StoreLocator
already has all functions for searching location by address and Position and getting coordinates by address
If you need to manage maps and autocomplete functionalities, you can use the built-in engines such as:
-
GoogleMap
: engine that implements all GoogleMap API v3 -
GoogleSearch
: engine that implements all GoogleAutocompleteService API v3 -
NaverMap
: engine that implements all NaverMap API v3 -
LocalSearch
: engine that implement LocalAutocomplete service based on LocalStorage
In order to use one (or more) of theese engines you have to addEngine
to StoreLocator
let storeLocator = new StoreLocator(...options...);
let promiseGmap = new GoogleMap(storeLocator, element, gmaps_options);
promiseGmap.then( (GMap) => {
storeLocator.addMapEngine('GoogleMap', GMap);
});
Map
engines you have to bind them to an HTMLElement
NOTE: in order to use Usage
Your HTML file could look like below
<div id="store-locator">
<div id="googlesearch" data-search-engine="GoogleAutocomplete" class="search"> </div>
<div id="googlemap" data-map-engine="GoogleMap" data-map-main="true" class="map"> </div>
<div class="map-controls">
<div class="zoom">
<div id="controls_zoom_in" class="in">+</div>
<div id="controls_zoom_out" class="out">-</div>
</div>
</div>
</div>
Your main javascript file should look like below
let storeLocator = new StoreLocator({
/* Key of `storeCode` into JSON */
"point-key": "storeCode",
/* Options will be passed to cluster official library */
ClusterMaxZoom: 13,
ClusterMinSize: 2,
ClusterGridSize: 60,
/* Options passed to Clusterer */
ClusterImagePath: "/images/store-locator-maps/cluster",
ClusterImageExt: "png",
/* Allowed types of address returned by google autocomplete */
AllowedAddressType: ["locality", "geocode", "country", "political", "route", "street_address"],
/* Max number of entries into LocalStorage */
maxlastentries: 5,
/* (debug) Show or hide a rectangle representing the bounding box into map */
ShowMapRectangle: false
});
let promiseGmap = new GoogleMap(storeLocator, $("#googlemap") );
let promiseGsearch = new GoogleSearch(storeLocator, $("#googlesearch") );
Promise.all( [promiseGmap, promiseGsearch]).then( (engines) => {
let GMap = engines[0], GSearch = engines[1];
storeLocator.addMapEngine('GoogleMap', GMap);
storeLocator.addSearchEngine('GoogleSearch', GSearch);
// StoreLocator is ready
storeLocator.navigate("New York").then( (data) => {
let bounds = data.bounds;
let all_results = data.results;
storeLocator.navigateLocation( bounds ).then( () => {
// Map has navigated to `bounds`
})
})
})
API
StoreLocator.search( String, Boolean )
Searches a given address via each search engine
. Returns a Promise
containing an array of array
of result as per below example
Pass true
as per second argument to restrict result to current viewport
Array result = [`SearchEngine1#SearchEngineResult`, `SearchEngine2#SearchEngineResult`, ..., `SearchEngineN#SearchEngineResult`];
SearchEngineResult
looks like:
SearchEngineResult = [{
main: 'Main Text',
other: 'Other text' || undefined
}]
StoreLocator.currentLocation(options)
Get current location via navigation.geolocation
API. Returns a LalLng object representing the current location
storeLocator.currentLocation().then( (obj) => {
console.log( "Current location is", obj.lat, obj.lng, "all data are", obj);
// You can now navigate to
storeLocator.navigate(null, obj)
}, (err) => {
// Error: No location
// User doesn't agree geolocation notification or got timeout or browser cannot retrieve location (err = storeLocator.Errors.NO_LOCATION )
// or
// No geolocation API (err = storeLocator.Errors.NO_GEOLOCATION )
});
StoreLocator.navigate( String, LatLng, Boolean )
Searches the given address (or the LatLng
coordinates) via Google GeoCoder
. Returns a Promise containing the bounding box
of the first result
The third argument will force MapProvider
to trigger change-address
event with a specific point
storeLocator.navigate("New York").then(function(bounds) {
console.info("Here are the bounds of the searched address", bounds);
});
// or
storeLocator.navigate(null, {lat: 8.55444, lng: 49.8887}, true).then(function(bounds) {
console.info("Here are the bounds of the searched location", bounds);
});
// It can returns also an error you can handle as per Promise rules:
storeLocator.navigate( "New York" ).then(function success(){}, function error(error) {
console.warn("An error occurred", error);
});
StoreLocator.navigateLocation( Bounds )
Once bounds
have been obtained via navigate
method, you can choose to move the map using this method.
It forces the navigation into the map engine. Returns a Promise you can catch in case of No Map Engine Found
error
Note: StoreLocator will use the first map engine that can handle the bounds
storeLocator.navigate("New York").then(function success(bounds){
storeLocator.navigateLocation( bounds ).then(function success(){
console.info("Map has navigated")
},
function error(err) {
console.warn("No map engine found", err);
}
});
StoreLocator.showPoint( Points, UseClusterer )
Show markers on map. You can specify if pins must be shown in Cluster or not.
Points
is a GeoJSON
object.
Returns a Promise containing an array of pin
storeLocator.showPoint(points, true).then(function(points){
$.each(points, function(i, point) {
var data = point.storeData; // Get the Store data from pin
point.on("click", function() {
// do something on click
console.info("You have clicked on pin", data);
});
});
});
StoreLocator.zoom = value
Sets the zoom level as delta
storeLocator.zoom = 1; // increase zoom level
storeLocator.zoom = -1; // decrease zoom level
StoreLocator.Map
Returns current map engine wrapper
StoreLocator.expandViewport( Point, Boolean )
Expands viewport of the map including given point
. If the second argument is true
, StoreLocator
will move the map to the returned bounds
var new_bounds = storeLocator.exandViewport({lat: 43.44333, lng: 131.34433});
// or
storeLocator.exandViewport({lat: 43.44333, lng: 131.34433}, true); // navigate to new bounds
StoreLocator.center = Point
Sets the point
as center of the map
Events
switchmap
StoreLocator#Fired when StoreLocator has changed the MapEngine
storeLocator.on("switchmap", function(e, prev, next) {
console.info("Previous map engine:", prev);
console.info("Next map engine:", next);
});
change-address
StoreLocator#Fired after navigate
method has been called
storeLocator.on("change-address", function(e, address, fixed_point) {
console.info("searched address is:", address);
console.info("fixed point is:", fixed_point);
});
navigateTo
StoreLocator#Fired after navigateLocation
has been called
storeLocator.on("navigateTo", function(e, map) {
console.info("MapEngine is:", map);
console.info("bound coordinates is:", map.bounds, "center:", map.center);
});
moveInMap
StoreLocator#Fired after map has changed its viewport as per zoom
or pan
interaction
storeLocator.on("moveInMap", function(e, map) {
console.info("MapEngine is:", map);
console.info("bound coordinates is:", map.bounds, "center:", map.center);
});
selectpoint
StoreLocator#Fired while clicking on a pin (the same of pin.on("click", function(){} );
)
storeLocator.on("selectpoint", function(e, map, pointer) {
console.info("MapEngine is:", map);
console.info("You have clicked on point:", pointer.storeData );
});
mapzoom
StoreLocator#Fired after map has changed its zoom level
storeLocator.on("mapzoom", function(e, prev, curr) {
console.info("Previuos zoom level:", prev);
console.info("Current zoom level:", curr);
});
mappan
StoreLocator#Fired after map has been panned and changed its viewport coordinates
storeLocator.on("mappan", function(e) {
console.info("Map has been panned");
});