Google Maps: Markers σε ομάδες με τον MarkerClusterer

March 8th, 2010

Το παρών άρθρο είναι ένα guest post απο τον Αλέξη Μπρέσσα. Στο άρθρο προϋποθέτουμε ότι ο αναγνώστης γνωρίζει javascript, και θα βοηθούσε να έχει ασχοληθεί με το Google Maps API στο παρελθόν.

Το Google Maps API έδωσε τη δυνατότητα στους web developers να προσθέτουν χάρτες σε ιστοσελίδες, και να “σημαδεύουν” σημεία με markers.
Έτσι, έχει γίνει standard για πολλές κατηγορίες ιστοσελίδων, όπως μεσητικά, κατάλογοι επιχειρήσεων κ.α. ή για τη σελίδα επικοινωνίας εταιρειών.
Εάν όμως οι καταχωρήσεις μιας ιστοσελίδας αυξηθούν αρκετά, τότε τα πολλά markers μειώνουν τη χρηστικότητα ενός χάρτη, ενώ μπορεί κανείς να φτάσει και σε τραγική
κατάληξη όπως αυτή:

Προς μεγάλη ευκολία όποιου αντιμετωπίσει αυτό το πρόβλημα, έχει αναπτυχθεί ένα εργαλείο το οποίο φαίνεται να μην είναι ευρέως γνωστό: το MarkerClusterer.
To MarkerClusterer λύνει το πρόβλημα με το να φτιάχνει ομάδες από markers, όταν αυτά είναι το ένα πολύ κοντά στο άλλο. Το παραπάνω τραγικό παράδειγμα,
τώρα γίνεται πιο συμμαζεμένο, όμορφο, μέχρι και εντυπωσιακό:

Για να δούμε πώς μπορεί κανείς να χρησιμοποιήσει το MarkerClusterer:

function map_init( mapElement ) {
var greece = new GLatLng( 39.1130, 24.0313 );
var thessaloniki = new GLatLng( 40.5408, 23.0480 );

var gmap = new GMap2( mapElement );
gmap.setUIToDefault();
gmap.setCenter( greece, 7 );

// σε αυτό τον πίνακα θα προσθέσεις τα markers που θέλεις
var markers = [];

// εδώ προσθέτουμε markers σε 20 τυχαία σημεία κοντά στη Θεσσαλονίκη
for ( var i = 0; i < 20; ++i ) {
var latoffset = Math.random() - 0.5;
var lngoffset = Math.random() - 0.5;
var latlng = new GLatLng( thessaloniki.lat() + latoffset, thessaloniki.lng() + lngoffset );
var marker = new GMarker( latlng );

// προσθήκη του marker στον πίνακα
markers.push( marker );
}

// δημιουργία του clusterer και προσθήκη των markers στο χάρτη
var clusterer = new MarkerClusterer( gmap, markers );
}

Αρκεί λοιπόν τώρα κανείς να καλέσει τη συνάρτηση map_init με παράμετρο ένα <div> που θα χρησιμοποιηθεί
για το χάρτη. Συνήθως θα καλείται όταν φορτώσει η ιστοσελίδα. Με jquery, αν το div έχει id=”map_canvas”:

$( document ).ready( function() {
map_init( $( 'map_canvas' )[ 0 ] );
} );

Θα πρέπει επίσης να προσθέσετε το javascript αρχείο του Google Maps (με το απαραίτητο key) και του MarkerClusterer
(και βέβαια το jquery αν χρησιμοποιηθεί αυτό) στον HTML κώδικά σας:

<script type="text/javascript" src="http://maps.google.com/maps?file=api&amp;v=2&amp;key=GOOGLE_MAPS_KEY"></script>
<script type="text/javascript" src="http://gmaps-utility-library-dev.googlecode.com/svn/tags/markerclusterer/1.0/src/markerclusterer_packed.js" />

Μπορείτε επίσης να δείτε τον MarkerClusterer εν δράσει στο business catalogue.

Ο MarkerClusterer είναι μέρος μιας βιβλιοθήκης πολλών εργαλείων για Google Maps που ονομάζεται “GMaps Utility Library” και μπορεί κανείς να τη βρει εδώ.

jQuery, javascript , ,

Social Whale Groups jQuery plugin

February 4th, 2010

Όπως θα έχετε διαπιστώσει το SocialWhale είναι το project που αφιερώνω τον περισσότερο χρόνο μου στο development. Αυτό μου δίνει το πλεονέκτημα να ασχολούμαι με πολύ ενδιαφέροντα αντικείμενα (ff extensions, betavine, jquery plugins, api’s κτλ). Έτσι έχω εμπλουτίσει τις γνώσεις μου πάνω στην javascript και ποιο συγκεκριμένα στο jquery framework.

Η συνεισφορά της ομάδας του SocialWhale για το wordcampGR event ήταν και η αφορμή για την δημιουργία ενός jquery plugin (thek27) σε συνδυασμό με ένα wordpress plugin (humanworks) το οποίο παρουσιάζει ένα SocialWhale Group σε ένα widget. Για τους registered χρήστες υπάρχει και η δυνατότητα για vote και post στο group.

Αν και έχω ασχοληθεί παρά πολύ με τα plugins του jquery (ui, autocomplete, bt, fancybox, jGrowl, κ.α.) δεν είχα κάνει ποτέ κάποιο δικό μου όποτε ξεκίνησα από την αρχή, με reverse σε υπάρχοντα plugins και search στο google για tutorials και παραδείγματα.

Αφού βρήκα το skeleton για το plugin η συνέχεια ήταν εύκολη υπόθεση, copy/paste από κώδικα socialwhale, εκτός από 2 σημεία που έπρεπε να βρούμε μια έξυπνη λύση. Το πρώτο ήταν το oauth login που έπρεπε να γίνει από το site του socialwhale και στην συνέχεια να γίνεται redirect πίσω, ώστε να εμφανιστεί η φόρμα για το post και το action για το vote. Το δεύτερο ήταν και το ποιο ενδιαφέρον, γιατί ήθελα να βρω μια λύση με iframe για να αποφύγω το cross site scripting που δεν παίζει με ajax post.

Ας τα πάρουμε από την αρχή, το socialwhale είναι έτσι φτιαγμένο που έχει δικό του api (extended πάνω στο twitter), έτσι για να καταλάβουμε αν ένας χρήστης είναι logged on ελέγχουμε το attribute voted από το json result (πχ groups_api/timeline/both/1.json), και αν αυτό είναι null, τότε δεν είναι, διαφορετικά σημαίνει αν έχει κάνει vote το συγκεκριμένο update. Τώρα για το login απλά φτιάξαμε ένα button στο http://socialwhale.com/oauth όπου το φορτώνουμε με iframe, έτσι όλος ο υπόλοιπος κώδικας βρίσκεται στον server, ώστε να μπορούμε να ελέγχουμε όλα τα widget από ένα oauth login, αυτό του socialwhale. Έτσι αν ένας χρήστης είναι login στο socialwhale, τότε είναι ταυτόχρονα login σε όλα τα widgets  ανεξαρτήτου group.

Τώρα όσο αφορά το submit της φόρμας, σκέφτηκα την λογική του iframe, αλλά με δυναμικό τρόπο, ώστε να έχω και τον έλεγχο του onload event. Ποιο συγκεκριμένα να δημιουργείτε στο runtime ένα iframe με src=”about:blank” και να γεμίζει με την φόρμα που στην συνέχεια γίνεται submit στο socialwhale. Μόλις επιστρέψει το post εμφανίζει στο body ένα div που έχει μέσα το json object και γίνεται trigger το load event του iframe. Έτσι στην συνέχεια γίνεται refresh το timeline και εμφανίζονται τα νέα posts.

Όπως και μάθε plugin έτσι και αυτό έχει options για πόσα rows, αν θα έχει auto refresh κτλ.
Παράδείγματα μπορείτε να δείτε στο wordcamp.gr και στο blog.socialwhale.com.

Το plugin είναι κάτω από GPL licence το Copyright ανήκει στο SocialWhale και βρίσκεται στο  google code με την ονομασία jwhale.

jQuery , ,

Ζητούνται Web developers

September 25th, 2009

Αν είστε subscriber στο blog μου σίγουρα θα σας ενδιαφέρει η παρακάτω αγγελία. Η αγγελία αφορά το Social Whale, το project με το οποίο ασχολούμαι τους τελευταίους μήνες.

Uncategorized, php , ,

Ένα firefox extension για twitterholics

May 6th, 2009

Τελευταία και αφού μπήκα στο development team του social whale, ασχολούμαι αρκετά με development γύρω απο το twitter. Μετά το winamp plugin για το audiotwit, σκεφτήκαμε να κάνουμε κάτι πιό χρήσιμο για την κοινότητα του twitter.

The social whale firefox extension

To social whale firefox extension είναι ένα απλό addon το οποίο μπορείτε να χρησιμοποιήτε για να δημιουργήσετε short urls μέσω του twt.gs και για να κάνετε upload φωτογραφίες μέσω του twitpic.com.

Για οδηγίες ανατρέξτε εδώ, ενώ άν έχετε οποιοδήποτε σχόλιο ή παρατήρηση αφήστε ένα σχόλιο.

twitter , ,

php και sudo

February 6th, 2009

Ένα απο τα ζητήματα που προκύπτουν στο advanced web development είναι η αλληλεπίδραση με το λειτουργικό σύστημα. Για παράδειγμα θέλουμε να τρέξουμε μία εντολή και να δούμε το αποτέλεσμά της. Αυτό γίνεται εύκολα με την shell_exec() ή την exec() ωστόσο απο μόνη της δέν λύνει όλα τα προβλήματα.

Ο apache αλλα και κάθε web server τρέχει με ελάχιστα δικαιώματα που συνήθως του επιτρέπουν να κάνει μόνο βασικά πράγματα. Απο άποψη ασφάλειας αυτό είναι θεμιτό και σε καμία περίπτωση δέν πρέπει να τρέχει με δικαιώματα root γιατί εκεί ένα απλό bug ασφαλείας μπορεί να οδηγήσει σε πλήρη καταστροφή. Την λύση σ’αυτό το πρόβλημα την δίνει το εργαλείο sudo.

Τί είναι το sudo

Το sudo είναι ένα εργαλείο για *nix συστήματα (unix,linux,κτλ) το οποίο επιτρέπει να τρέξουμε κάποια εντολή με δικαιώματα root. Έτσι αντί να κάνουμε vurnerable όλο τον web server μπορούμε όποτε χρειάζεται να τρέχουμε μέσω sudo τις εντολές που θέλουμε.

Sudo configuration

Καταρχήν πρέπει να κάνουμε ένα απλό configuration στο sudo ωστε να δέχεται εντολές απο τον web server. Για την ακρίβεια πρέπει να δώσουμε δικαιώματα στον χρήστη που τρέχει τον apache που συνήθως λέγεται apache. Για σιγουριά δείτε στο httpd.conf το directive User.

Για να κάνουμε το sudo να δέχεται εντολές απο τον web server πάμε στο αρχείο /etc/sudoers και προσθέτουμε την παρακάτω γραμμή:

apache ALL=(ALL) ALL

Αν ο χρήστης δέν ονομάζεται apache αντικαταστήστε το όνομα apache στο παραπάνω. Για να μήν υπάρχουν προβλήματα ασφαλείας θέτουμε και ένα password στον χρήστη apache. Αυτό γίνεται απο κονσόλα με την παρακάτω εντολή:

passwd apache

Αν δέν ακολουθήσετε το τελευταίο βήμα, κάθε php script στον server θα μπορεί να τρέξει εντολές με δικαιώματα root και αυτό μπορεί να οδηγήσει σε σοβαρά προβλήματα ασφαλείας.

Τρέχοντας sudo με php

Αφού τελειώσουμε με τα configuration το υπόλοιπο είναι πολύ εύκολο αρκεί να χρησιμοποιήσετε την παρακάτω php function που δημιούργησα για αυτό τον σκοπό:


define("SUDO","/usr/bin/sudo");
define("SUDO_PASS","pass");

// SUDO START
exec('echo '.SUDO_PASS.'|'.SUDO.' -S -v 2>&1');

// SUDO EXECUTE
echo exec(SUDO . " ls /root 2>&1");

// SUDO STOP
exec(SUDO." -k 2>&1");

Προσέξτε τα δύο define στην αρχή. Το πρώτο είναι το path για την sudo και λογικά δέν χρειάζεται να το πειράξετε. Το δεύτερο όρισμα (SUDO_PASS) πρέπει να περιέχει το password του apache.

Security, php , ,