neveldo / jQuery-Mapael

jQuery plugin based on raphael.js that allows you to display dynamic vector maps
https://www.vincentbroute.fr/mapael/
MIT License
1.01k stars 195 forks source link

click on area causes zoom to fit to viewport? #260

Closed tammo0 closed 7 years ago

tammo0 commented 8 years ago

Hi @neveldo,

first of all: thanks again for your great work!

i'm looking for a feature: When a user clicks an area like a country i want the map to focus on it, so it fits to the viewport including zoom. As far as i know its just possible to zoom to a lat/lon location with a given zoom level at the moment. But for areas its not that easy because they are paths and not coordination values. So i wonder if there is a function to do what i need (e.g. using BBox or something).

thanks and greetings

neveldo commented 8 years ago

HI @tammo0 ,

You're welcome :) . For now, there is unfortunately not such a feature into Mapael. I think that with getBBox() function and paper.setViewBox() (this one is used for zooming), you should be able to do something.

Feel free to give a feedback !

Indigo744 commented 7 years ago

@neveldo I would like to update onZoomEvent() and the zoomOptions parameters, as follow:

        /*
         * Zoom on the map
         *
         * zoomOptions.animDuration zoom duration
         *
         *  IF you want to zoom to a specific coordinate:
         *      zoomOptions.level        level of the zoom between minLevel and maxLevel (absolute number, or relative string +1 or -1)
         *      zoomOptions.fixedCenter  set to true in order to preserve the position of x,y in the canvas when zoomed
         *
         *      zoomOptions.x            x coordinate of the point to focus on
         *      zoomOptions.y            y coordinate of the point to focus on
         *      - OR -
         *      zoomOptions.latitude     latitude of the point to focus on
         *      zoomOptions.longitude    longitude of the point to focus on
         *      - OR -
         *      zoomOptions.plot         plot ID to focus on
         *  If no coordinates are specified, the zoom will be focused on the center of the map
         *
         *  IF you want to zoom to a specific area:
         *      zoomOptions.x1            left coordinate of the visible part
         *      zoomOptions.y1            top coordinate of the visible part
         *      zoomOptions.x2            right coordinate of the visible part
         *      zoomOptions.y2            bottom coordinate of the visible part
         *      - OR -
         *      zoomOptions.lat1          top latitude of the visible part
         *      zoomOptions.long1         left longitude of the visible part
         *      zoomOptions.lat2          bottom latitude of the visible part
         *      zoomOptions.long2         right longitude of the visible part
         *      - OR -
         *      zoomOptions.area          area ID to focus on
         *
         */
        onZoomEvent: function (e, zoomOptions) {

I'm adding:

  1. Zooming on plot name (zoomOptions.plot)
  2. Zooming on area name (zoomOptions.area)
  3. Zooming on area coordinate (zoomOptions.x1 ...)

What do you think? It should cater to most usage...

neveldo commented 7 years ago

I agree with you, it looks good to me !

(maybe it will be a little tricky to handle area zooming and setting the proper zoom level depending on the area size however).

Indigo744 commented 7 years ago

After some though, I want to simplify the signature and propose the following options:

        /*
         * Zoom on the map
         *
         * zoomOptions.animDuration zoom duration
         *
         * zoomOptions.level        level of the zoom between minLevel and maxLevel (absolute number, or relative string +1 or -1)
         * zoomOptions.fixedCenter  set to true in order to preserve the position of x,y in the canvas when zoomed
         *
         * zoomOptions.x            x coordinate of the point to focus on
         * zoomOptions.y            y coordinate of the point to focus on
         * - OR -
         * zoomOptions.latitude     latitude of the point to focus on
         * zoomOptions.longitude    longitude of the point to focus on
         * - OR -
         * zoomOptions.plot         plot ID to focus on
         * - OR -
         * zoomOptions.area         area ID to focus on
         * zoomOptions.areaMargin   margin (in pixels) around the area
         * 
         * If an area ID is specified, the algorithm will override the zoom level to focus on the area
         * but it may be limited by the min/max zoom level limits set at initialization.
         *
         * If no coordinates are specified, the zoom will be focused on the center of the current view box
         *
         */
        onZoomEvent: function (e, zoomOptions) {

Because allowing a user to specify (x1, y1) to (x2, y2) has some weird implication with the zoom level and the map actual ratio.

So in the end, the main additions are adding zoomOptions.plot and zoomOptions.area.

neveldo commented 7 years ago

Indeed I got the tricky point with a zoom by coordinates and the current level.

I was just thinking about an option such as the areaMargin after my first answer :)

What should be the best way to handle area zooming ? It could be great to have a simple behavior in which the user set an area to zoom-in and a zoom level. Moreover, in order to go further, we could also make the zoom level optional, in order to compute the proper level depending on the area size and the areaMargin value. Maybe it could be tricky however ...

Just a thought, maybe you have already yours : we could compute the width and height of the visible part of the map for each available zoom level. Then, with the getBBox() info from the area to zoom in, we could determine which is the best zoom level that closestly "encompass" the area.

Indigo744 commented 7 years ago

I will indeed try to make it simple: if only area is defined, the whole viewport (minus the margin) will be used to zoom as much as possible (with respect to max zoom level), but if a zoom level is set, then it will work like a zoom to a specific coordinates, the coordinates being computed from the area BBox.

I have a branch almost done and ready for PR. I need to find more time to clean it and fix a little remaining bug. Coming soon ;-)

neveldo commented 7 years ago

Hello @Indigo744 , it sounds good, eager to see it !