Skip to content

Commit

Permalink
Markers extension
Browse files Browse the repository at this point in the history
Extends the marker-related functionalities of the jHERE core by adding support for group of markers.
  • Loading branch information
mmarcon committed Mar 20, 2013
1 parent b9c7e73 commit 1e9c1ed
Show file tree
Hide file tree
Showing 5 changed files with 335 additions and 5 deletions.
43 changes: 42 additions & 1 deletion EXTENSIONS.md
Expand Up @@ -94,4 +94,45 @@ into an address. This call is asynchronous
and supports a `success` and a `error` callback.
When jHERE is used with jQuery a $.Deferred object is also returned
and can be used instead of callbacks. For Zepto.JS a Deferred is also returned,
however note that it is a custom implementation that only supports the `done` method.
however note that it is a custom implementation that only supports the `done` method.

### shapes extension

With the shapes extension it is possible to draw circles, rectangles, polylines and polygons on the map canvas.

The syntax is the following:

$('.selector').jHERE('shape', 'circle', {center: position, radius: integer, style: object});
/*or*/ $('.selector').jHERE('circle', {center: position, radius: integer, style: object});

$('.selector').jHERE('shape', 'rectangle' {topLeft: position, bottomRight: position, style: object});
/*or*/ $('.selector').jHERE('rectangle' {topLeft: position, bottomRight: position, style: object});

$('.selector').jHERE('shape', 'polyline', {points: array, style: object}));
/*or*/ $('.selector').jHERE('polyline', {points: array, style: object}));

$('.selector').jHERE('shape', 'polygon', {points: array, style: object});
/*or*/ $('.selector').jHERE('polygon', {points: array, style: object});

`style` is always an object that defines the way the shape looks. Can be specified as in the JSLA API (pen, brush, see [here](http://developer.here.net/apiexplorer/index.html#examples/js/shapes/map-with-shapes/)) or in a simpler way as follows:

{
stroke: "#CC0000FF", //RGBA
fill: "#000000AA", //RGBA
thickness: 1 //px
}

### markers extension

Extends the marker-related functionalities of the jHERE core by adding support for group of markers.

It adds support for the `group` option for a marker. Groups can be then hidden or shown with a call to

$('.selector').jHERE(['group0', 'group1'], true);

First parameter is a group name (`String`) or an `Array` of group names. Second parameter is a `boolean`, for visible (`true`) or not visible (`false`).

This extansion is useful when it is necessary to categorize (i.e. group) markers and enable the capability of showing/hiding certain categories of markers.

//Stupid example: show all Burger Kings and hide all the Mc Donalds
$('.map').jHERE('b-king', true).jHERE('mc-donald', false);
1 change: 1 addition & 0 deletions dist/extensions/markers.min.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

92 changes: 92 additions & 0 deletions src/examples/example.markers.html
@@ -0,0 +1,92 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<title>HTML5 boilerplate—all you really need…</title>
<style>
#map {
position: absolute;
top: 0;
left: 0;
bottom: 80px;
right: 0;
background: white;
}

ul {
position: absolute;
bottom: 0;
left: 0;
right: 0;
margin: 0;
padding: 0;
background: #222;
height: 80px;
}

li {
display: inline-block;
font-family: 'American Typewriter', sans-serif;
font-weight: 100;
font-size: 24px;
padding: 24px 10px;
line-height: 1;
cursor: pointer;
color: #fff;
border-right: 1px dotted #666;
}

li.active.restaurants,
li.restaurants:hover {
color: #9fd067;
}

li.active.hotels,
li.hotels:hover {
color: #ff7f50;
}
</style>
</head>

<body>
<div id="map"></div>
<ul class="toolbar">
<li data-group="restaurants" class="restaurants active">
Restaurants
</li>
<li data-group="hotels" class="hotels active">
Hotels
</li>
</ul>
<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.8.2/jquery.min.js"></script>
<!-- <script type="text/javascript" src="//cdnjs.cloudflare.com/ajax/libs/zepto/1.0rc1/zepto.min.js"></script> -->
<!-- <script type="text/javascript" src="../zepto.adapter.js"></script> -->
<script type="text/javascript" src="../jhere.js"></script>
<script type= "text/javascript" src="../extensions/markers.js"></script>
<script type="text/javascript">
$(window).on('load', function(){
$('#map').jHERE({
center: [52.5, 13.3],
zoom: 12
})
.jHERE('marker', [52.46, 13.31], {group: 'hotels', fill: '#ff7f50'})
.jHERE('marker', [52.51, 13.3], {group: 'hotels', fill: '#ff7f50'})
.jHERE('marker', [52.512, 13.35], {group: 'hotels', fill: '#ff7f50'})

.jHERE('marker', [52.5, 13.3], {group: 'restaurants', fill: '#9fd067'})
.jHERE('marker', [52.5, 13.35], {group: 'restaurants', fill: '#9fd067'})
.jHERE('marker', [52.52, 13.3], {group: 'restaurants', fill: '#9fd067'})
.jHERE('marker', [52.51, 13.27], {group: 'restaurants', fill: '#9fd067'})
.jHERE('marker', [52.52, 13.34], {group: 'restaurants', fill: '#9fd067'})
.jHERE('marker', [52.48, 13.4], {group: 'restaurants', fill: '#9fd000', click: function(e){
alert('Click!');
}});

$('li').on('click', function(e){
$('#map').jHERE('markergroups', $(this).data('group'), !$(this).hasClass('active'));
$(this).toggleClass('active');
});
});
</script>
</body>
</html>
196 changes: 196 additions & 0 deletions src/extensions/markers.js
@@ -0,0 +1,196 @@
/*
Copyright (c) 2012 Massimiliano Marcon, http://marcon.me
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
"Software"), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
;(function($){
var _ns, marker, nomarkers,
markergroups,
_defaults = {
text: '',
textColor: '#333333',
fill: '#ff6347',
stroke: '#333333',
shape: 'balloon',
icon: undefined,
group: '_'
}, bind = $.proxy,
/*Map and marker supported events*/
mouse = 'mouse', click = 'click', drag = 'drag', touch = 'touch', start = 'start', end = 'end', move = 'move',
supportedEvents = [
click,
'dbl' + click,
mouse + 'up',
mouse + 'down',
mouse + move,
mouse + 'over',
mouse + 'out',
mouse + 'enter',
mouse + 'leave',
'longpress',
drag + start,
drag,
drag + end,
'resize',
touch + start,
touch + end,
touch + move
];

//### Add markers to the map
//`$('.selector').jHERE('marker', positionObject, markerOptions);`
//
//`positionObject` can be an object of type
//
//`{latitude: -43, longitude: 55}`
//
//or an array
//
//`[-43, 55]`
//
//`markerOptions` can be an object of type
//<pre><code>{
// text: '!',
// textColor: '#333333',
// fill: '#ff6347',
// stroke: '#333333',
// icon: 'urlToIcon',
// anchor: {x: 12, y: 18} //an icon 24x36 would result centered
// click: function(event){/*this is the element, event.geo contains the coordinates*/},
// dblclick: function(event){/*this is the element, event.geo contains the coordinates*/},
// mousemove: function(event){/*this is the element, event.geo contains the coordinates*/},
// mouseover: function(event){/*this is the element, event.geo contains the coordinates*/},
// mouseout: function(event){/*this is the element, event.geo contains the coordinates*/},
// mouseenter: function(event){/*this is the element, event.geo contains the coordinates*/},
// mouseleave: function(event){/*this is the element, event.geo contains the coordinates*/},
// longpress: function(event){/*this is the element, event.geo contains the coordinates*/},
// group: 'restaurants'
//}</code></pre>
//All parameters are **optional**.
marker = function(position, markerOptions) {
var markerListeners = {},
centralizedHandler = bind(triggerEvent, this),
mc = this._mc,
MarkerConstructor = 'Marker',
marker, groups;
this.groups = this.groups || {};
groups = this.groups;
_ns = _ns || nokia.maps;
$.each(supportedEvents, function(i, v){
markerListeners[v] = [centralizedHandler, false, null];
});

markerOptions = $.extend({}, _defaults, markerOptions);
/*Normalize settings*/
markerOptions.textPen = markerOptions.textPen || {strokeColor: markerOptions.textColor};
markerOptions.pen = markerOptions.pen || {strokeColor: markerOptions.stroke};
markerOptions.brush = markerOptions.brush || {color: markerOptions.fill};
markerOptions.eventListener = markerListeners;

if (!markerOptions.icon) {
MarkerConstructor = 'Standard' + MarkerConstructor;
}

marker = new _ns.map[MarkerConstructor](position, markerOptions);
groups[markerOptions.group] = groups[markerOptions.group] || [];
/*
If the group has just been created, make it visible,
if not leave the visibility as it is
*/
groups[markerOptions.group].visible = groups[markerOptions.group].length === 0 ? true : groups[markerOptions.group].visible;
groups[markerOptions.group].push(marker);

/*Only add the marker to the map when its group is visible*/
if(groups[markerOptions.group].visible) {
mc.objects.add(marker);
}
};

//### Show/hides group of markers
//`$('.selector').jHERE(['group0', 'group1'], true);`
//
//First parameter is a group name (String) or an Array of
//group names.
//Second parameter is a boolean, for visible (`true`) or not visible (`false`).
markergroups = function(targetgroups, visible) {
var mc = this._mc, objs = mc.objects, groups;
this.groups = this.groups || {};
groups = this.groups;
targetgroups = (targetgroups instanceof Array ? targetgroups : [targetgroups]);
$.each(targetgroups, function(i, g){
if(visible) {
objs.addAll(groups[g] || []);
}
else {
objs.removeAll(groups[g] || []);
}
groups[g].visible = !!visible;
});
};

//### Remove all the markers from the map
//`$('.selector').jHERE('nomarkers');`
nomarkers = function(){
this._mc.objects.clear();
this.groups = {};
};


/*
Following is copy-pasted from jhere.js, but I can't
see another way of doing this without exposing this stuff that
is supposed to be private
*/

function triggerEvent(event) {
var target = event.target, handler = target[event.type];
if (isFunction(handler)) {
/*
When the event listener is called then
the context is the DOM element containing the map.
*/
handler.call(this.element, makeGeoEvent(event, target.coordinate));
}
}

/*
*********************************************
*********************************************
*/

function makeGeoEvent(event, position) {
return $.Event(event.type, {
originalEvent: event,
geo: {
latitude: position.latitude,
longitude: position.longitude
},
target: event.target
});
}

function isFunction(fn) {
return typeof fn === 'function';
}

$.jHERE.extend('marker', marker);
$.jHERE.extend('markergroups', markergroups);
$.jHERE.extend('nomarkers', nomarkers);
}(jQuery));
8 changes: 4 additions & 4 deletions src/jhere.js
Expand Up @@ -519,7 +519,7 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
// //map is the JSLA map object
// //here is the whole JSLA API namespace
//}</code></pre>
H.originalMap = function(closure){
H.originalMap = function(closure) {
/*
Be a good citizen:
closure context will be the DOM element
Expand Down Expand Up @@ -555,7 +555,7 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
/*
Undocumented, on purpose.
*/
H.destroy = function(){
H.destroy = function() {
this.map.destroy();
$.removeData(this.element);
$(this.element).empty();
Expand Down Expand Up @@ -642,7 +642,7 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
jQuery <= 1.7 does not have on.
*/

function isSupported(){
function isSupported() {
return !!$().on;
}

Expand Down Expand Up @@ -712,7 +712,7 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//});</code></pre>
//
//A good example of extension is the [routing extension](https://github.com/mmarcon/jhere/blob/master/src/extensions/route.js).
P.extend = function(name, fn){
P.extend = function(name, fn) {
if (typeof name === 'string' && isFunction(fn)) {
H[name] = fn;
}
Expand Down

0 comments on commit 1e9c1ed

Please sign in to comment.