Jump to content

How would you do this?


heldercervantes
 Share

Recommended Posts

Take this page as an example: http://www.jacinto-lda.com/en/internacional

There's a background image and several "pages" with X Y coordinates over said image.

I'm stuck on how to get something like this manageable on PW admin. A couple of fields for inputting coordinates would solve it, but there's no usability in that.

In our proprietary CMS we'd have a positioning system much like InputfieldMapMarker where you see the background image and drag the marker to wherever you want it to appear.

Any ideas on how to get something like this working on PW?

In this case the image is static, but I have another site where I need to upload the background image and then add several markers over it.

thanks,

HC

Link to comment
Share on other sites

Hi Rick!

I use InputfieldMapMarker for the lat/lng coordinates (used for google/mapbox maps mainly) and the code from the SO link to convert the lat/lng to x/y pixel coordinate dynamicly. I'm only using the conversion on one image but i guess you could use 

$image->width
$image->height 

to make it work with uploaded images.

Link to comment
Share on other sites

Here's the code:

function convertGeoToPixel($lat, $lon)
  {
        $mapWidth = 38;
        $mapHeight = 109;

        $mapLonLeft = 16.37007904846189;
        $mapLonRight = 17.151481636352514;
        $mapLonDelta = $mapLonRight - $mapLonLeft;

        $mapLatBottom = 56.1947686858922;
        $mapLatBottomDegree = $mapLatBottom * M_PI / 180;

      $x = ($lon - $mapLonLeft) * ($mapWidth / $mapLonDelta);

      $lat = $lat * M_PI / 180;
      $worldMapWidth = (($mapWidth / $mapLonDelta) * 360) / (2 * M_PI);
      $mapOffsetY = ($worldMapWidth / 2 * log((1 + sin($mapLatBottomDegree)) / (1 - sin($mapLatBottomDegree))));
      $y = $mapHeight - (($worldMapWidth / 2 * log((1 + sin($lat)) / (1 - sin($lat)))) - $mapOffsetY);

      return array($x, $y);
  }
$pposition = convertGeoToPixel($pl->map->lat, $pl->map->lng);
echo  "<div class='litenkarta'><div class='punkt' style='left: {$pposition[0]}px; top: {$pposition[1]}px; '></div></div>";
  • Like 3
Link to comment
Share on other sites

Hi heldercervantes,

Just off the top of my head, there are a couple of approaches you could take.

The drag and drop approach you suggested in your original post of placing a marker (pseudo-callout) is probably the most user-friendly with images whose 'content' is not consistent (ie, automobiles, furniture, etc). A page containing the image, with sub-pages containing a marker icon and associated text content for each position would be my approach, along with the drag and drop js utility.

There could be other options more PW-specific that the members who are much smarter than me might be able to offer.

Link to comment
Share on other sites

you could also create one regular image field and trigger clicks on that image via jquery http://stackoverflow.com/questions/2159044/getting-the-x-y-coordinates-of-a-mouse-click-on-an-image-with-jquery . you could then trigger an "add new" event on a pagetable and fill the coordinates that you got from the click offset. editing existing items would be more difficult though...

just to throw in an idea :)

Link to comment
Share on other sites

The frontend part is relatively simple. I built the example on my initial post.

This is how each spot is edited on our proprietary CMS:

cms.jpg

So basically in the CMS we have the image and a draggable marker. In this case the mother image is fixed, but in other projects the image was uploaded by the user and then multiple markers could be added, with similar results to cstevensjr's example.

We need this kind of inputfield on PW, but building such a module would be beyond my capabilities, I'm afraid.

Link to comment
Share on other sites

@heldercervantes,

How did you build the on in your 'CMS'? (i.e. what web technologies)...Maybe it could be converted to a Fieldtype, but we would have to see the underlying code...(if at all possible)...

In this case it's a bit hardcoded on the CMS itself. What we have there is just a DIV with the image and a draggable dot (using jQuery UI). Whenever the dot is moved, the X and Y coordinates are stored in hidden input fields.

I made a quick usable sketch here: http://heldercervantes.com/experiments/ifim/

In cases where the image isn't fixed, there's a separate field for uploading it that needs to be in a parent page.

I wouldn't know where to begin making a new fieldtype, but it anyone wants to have a go at it, I'd gladly help out.

Link to comment
Share on other sites

OK, that looks pretty much straightforward. Seems the js will be doing most of the heavy lifting. All the Fieldtype/Inputfield will do is so display and save the data (of course ;-)). A couple of questions:

  1. How many dots per image; single or multiple? [am guessing multiple]
  2. Save when you hit a button save or ajax? [am guessing button; otherwise, potentially too many ajax requests]
  3. How many 'maps' on one page? Single or multiple?

Edit:

Aah, I see some of my questions have been answered in your earlier posts.

In your present CMS, how do you edit a point? You click on the dot? Or you edit entries in some table?

Edited by kongondo
Link to comment
Share on other sites

1.

Multiple dots per image. In the Jacinto website, the map is fixed and the admin can't change it anywhere. Think of the map as a setting in the field itself, and each location is a page.

Imagining a product with several dots for pointing out features, there would have to be a parent page where you upload the image, and subpages for each dot. Each dot page would grab the background image from the parent product page.

2.
I agree. Save button. Less requests and more fool proof. That's when we save it on our cms.

3.

Single. Looking at the first example, we're in the "international" page, and there are subpages for each location.

--

Maybe the best way to make this flexible enough for whatever use is a combination of two specific input fields.

The first, let's call it ImageMarkerBackground, would be placed in the parent and allow 1 image to be uploaded.

Then there would be ImageMarker, used on the child page, referencing the parent's ImageMarkerBackground to show the correct image, where the user places the dot.

Result: Admin ads a "world" page and uploads the map, then creates as many "location" subpages as needed. Same for a product photo and features or whatever else.

Link to comment
Share on other sites

Its not clear to me why each dot should be a sub/child-page? Apart from co-ordinates, what other information does the sub-page hold?  if it's simple info, can't the dots all be in a single 'table'?,  (similar to the events fieldtype), i.e.

x         y           info 1     info 2     info 3

34      336        aaa         bbb         ccc

Link to comment
Share on other sites

In addition to kongondo's questions, do you want a one-to-one relationship between a user and a map? That is:

Do you want each user to upload one or more maps, and subsequently add location data for each map (one-to-many),

or,

Do you want one map where multiple users add location data to it (many-to-one),

or,

Do you want one map per user (one-to-one)?

Link to comment
Share on other sites

@kongondo: It's just a matter of flexibility. In the Jacinto example, each dot only has a few infos that can be solved using that approach, but you may need a textarea, an extra photo (or a gallery), referencing other pages, etc.

Here's another example: http://www.aldeco.pt/p50-environments-en

Each photo in this gallery references products. So each dot would need a page selector, so the end user can jump to the product page.

Another: http://www2.inapalmetal.pt/en/products

When the page loads, you'll see a wireframe of a car, click it and wait for the animation to end to see the dots. Each dot has an image + title.

Last one: http://extranet.frontend.pt/alfandegaporto2015/pt/espacos/sala-do-arquivo

In this one there's a main photo of the room, and each dot has an image + description.

Link to comment
Share on other sites

In addition to kongondo's questions, do you want a one-to-one relationship between a user and a map? That is:

Do you want each user to upload one or more maps, and subsequently add location data for each map (one-to-many),

or,

Do you want one map where multiple users add location data to it (many-to-one),

or,

Do you want one map per user (one-to-one)?

Don't know if I understood correctly. The first option seems the correct one, but you mention users and that makes me think you're getting the wrong idea.

Creating or editing the map or locations isn't something to make available to the site's users. I'm talking about tools to edit in PW's admin.

That said, it's a one-to-many solution. A map with multiple locations, a product photo with multiple features, or an environment photo pointing out multiple products.

Link to comment
Share on other sites

@heldercervantes,

OK, I see. Make sense. However, I think all the editing of the 'dots' should happen in one place. The sub-pages should just be referenced (by the dot in the parent page) and will contain all the secondary info (i.e., not the coordinates) about that 'dot', e.g. location, color, price, whatever. In fact, the referenced sub-pages do not have to be child pages of the page with the dots. The sub-pages are just info pages. The info they contain can be reused by any 'dot' page.

Here's how I see it:

Let's take the example of the Room Archive.

  1. We'll have a template called 'products' with the Field ImageMarkup (or whatever you call it). This field allows for the uploading of an image and the 'marking-up' of that image. Let's say we create a page called 'Room Archive' that uses this template and we upload to it the image of a 'room' [or part of a building]. 
  2. Let's say we also have pages that contain information about 'dots'. These pages could be using any template, with any number of fields, with all sorts of information. Let's call these 'info pages'. Some of the 'info pages' contain information about our Room Archive, others contain info about other similar product pages, and some of the info could also be common to all products.
  3. Each dot placed on our 'Room Archive' image references some other page on our page tree with info that we need. Our 'Room Archive' page doesn't care what that info is. For instance, it doesn't care whether that info is about the materials used in the building, or the colours, or the size of the door, etc. That info, for all intents and purposes, will be accessed via the API much like ProcessWire's page fields. A page referencing another page in its pagefield doesn't care what that other page does. All it saves is the ID of that referenced page. With that single info, using the API, you can access and display and manipulate every little bit of info about the referenced page.
  4. So, back to our example, the 'Room Archive' page [or the 'dots' page if you like] only needs to save three bits of data. The x-coordinate of the dot, the y-coordinate of the dot, and the ID of the (info) page referenced by these coordinates. Nothing more. 
  5. Then, similar to how we access page objects stored in a pagefield, for each saved 'trio' of data, our Field will return an object of each referenced page as well as the coordinates. We then use these to output whatever we like in our template file for display to the user. E.g. $page->image_markup->title, $page->image_markup->description, whatever.
  6. This way, we edit all dots for 'Room Archive' in one place, rather than in the 'info' pages themselves. If the information in the 'info' pages change, the 'Room Archive' doesn't care, it still has a reference to the info page. The 'Room Archive' page also doesn't care how our 'info' pages are organised.

This is how I would do it, unless there's something am missing...

Edited by kongondo
  • Like 1
Link to comment
Share on other sites

I like your process for the room archive, kongondo.

The only difference I was thinking was to create the dots on-the-fly by dragging a dot-type from a legend onto the image, then having a popup dialog box where the user can add the data associated with that specific dot. So we'd have the parent image-page with child dot-pages, which contains x,y, name, description, etc.

I don't have the experience with PW yet, so this would have been my initial approach.

Link to comment
Share on other sites

Makes sense to me. Single inputfield, and in the environments example, your approach would mean one less page per dot. AND you'd get to see and adjust all dots in the same place, which is great.

The interface for editing on the admin would need to be a bit more complex. You'd need:

  • Button for adding dots;
  • A list of the current dots with the page selector and a delete button;
  • Clicking/dragging a dot would hilight that dot on the list;
  • Clicking an entry on the list would hilight the dot on the image and pull the z-index to top (so you can handle overlapped dots).
Link to comment
Share on other sites

Button for adding dots;

Not too difficult

A list of the current dots with the page selector and a delete button;

Easy as the list comes from the saved values in the DB. Using $config->js, we send saved coordinates to javascript to show saved coordinates on the map/image.

Clicking/dragging a dot would highlight that dot on the list;

jQuery :-) [not my strong point]

Clicking an entry on the list would highlight the dot on the image and pull the z-index to top (so you can handle overlapped dots).

jQuery + CSS

  • Like 1
Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...