Trigger Layer(s) Popup with Feature.Geometry

3893
16
Jump to solution
11-05-2014 08:48 AM
BrianO_keefe
Regular Contributor II

The simple version of this question is...

Can I trigger a specific layers popup / click response using a feature.geometry point?

The more involved version is as follows...

I have some simple maps, MyWatershed, Council Districts, etc. Currently the user opens the map, enters their address, and then has to click on the map to find out what watershed or council district they are in. I would like to circumvent that. I want the user to enter their address and then wherever that dot / popup (titled "Location") shows up, instead of showing it... trigger a click event / popup for a specific layer at that point.

I found the place in the Geocoder widget where this event gets fired...

/widgets/Geocoder/Widget.js : line 238

        if (feature) {

          this.map.infoWindow.setTitle("Location");

          this.map.infoWindow.setContent(content || null);

          this.map.infoWindow.show(feature.geometry);

  

        } else if (extent) {

          this.map.setExtent(extent);

        }

I "believe" that I can interrupt the this.map.infoWindow.show command, and step in and fire off a click even at feature.geometry instead. Still researching but if anyone has a better direction, please advise!

1 Solution

Accepted Solutions
RobertScheitlin__GISP
MVP Esteemed Contributor

Brian,

  Try this:

          console.info(content);

          // First thing we need to do is convert the feature.geometry to a "mapPoint" object         

          var mpPt = feature.geometry;

          console.log( "Map Point is set." );

          this.map.centerAndZoom(mpPt,16);

          console.log( "Center and Zoom" );

          // Once we have the "mapPoint" object we convert it to a "screenPoint" object

          setTimeout(lang.hitch(this, function(){

            var scrPt = map.toScreen(mpPt);

            this.map.emit("click", { bubbles: true, cancelable: true, screenPoint: scrPt, mapPoint: mpPt });

          }), 500);

View solution in original post

16 Replies
BrianO_keefe
Regular Contributor II

It looks like someone has figured this out.

https://community.esri.com/message/395853#395853

Thomas Rippetoe wrote:

You can 'value add' a 'mapPoint' and/or 'screenPoint' objects to the click event. I think 'mapPoint' might be the object you are looking for. I have done something like this (I am pretty sure that i am not doing  'screenPoint' correctly - that's why i am using mapPoint):

var scrPt = new Point(-122, 45.6);

var mpPt = new Point(-122, 45.6);

map.emit("click", { bubbles: true, cancelable: true, screenPoint: scrPt, mapPoint: mpPt });

So now I just need to find a way to convert feature.geometry to either a ScreenPoint or a MapPoint.

0 Kudos
RobertScheitlin__GISP
MVP Esteemed Contributor

Brain,

  Here is a sample using just JS API (not WAB stuff).

<!DOCTYPE html>

<html>

  <head>

    <meta http-equiv="Content-Type" content="text/html; charset=utf-8">

    <!--The viewport meta tag is used to improve the presentation and behavior of the samples

      on iOS devices-->

    <meta name="viewport" content="initial-scale=1, maximum-scale=1,user-scalable=no">

    <title>Popup</title>

    <link rel="stylesheet" href="http://js.arcgis.com/3.11/dijit/themes/claro/claro.css">

    <link rel="stylesheet" href="http://js.arcgis.com/3.11/esri/css/esri.css">

    <style>

      html, body, #map {

        padding: 0;

        margin: 0;

        height: 100%;

      }

      /* Change color of icons to match bar chart and selection symbol */

      .esriPopup.dark div.titleButton,

      .esriPopup.dark div.titlePane .title,

      .esriPopup.dark div.actionsPane .action {

        color: #A4CE67;

      }

      /* Additional customizations */

      .esriPopup.dark .esriPopupWrapper {

        border: none;

      }

      .esriPopup .contentPane {

        text-align: center;

      }

      .esriViewPopup .gallery {

        margin: 0 auto;

      }

     

      #search {

        display: block;

        position: absolute;

        z-index: 2;

        top: 20px;

        left: 74px;

      }

    </style>

    <script src="http://js.arcgis.com/3.11/"></script>

    <script>

      var map;

      require([

        "esri/map", "dojo/dom", "esri/geometry/Point",

        "esri/dijit/Popup", "esri/dijit/PopupTemplate",

        "esri/layers/FeatureLayer", "esri/dijit/Geocoder",

        "esri/symbols/SimpleFillSymbol", "esri/Color",

        "dojo/dom-class", "dojo/dom-construct", "dojo/on",

        "dojox/charting/Chart", "dojox/charting/themes/Dollar",

        "dojo/domReady!"

      ], function(

        Map, dom, Point,

        Popup, PopupTemplate,

        FeatureLayer, Geocoder,

        SimpleFillSymbol, Color,

        domClass, domConstruct, on,

        Chart, theme

      ) {

        //The popup is the default info window so you only need to create the popup and

        //assign it to the map if you want to change default properties. Here we are

        //noting that the specified title content should display in the header bar

        //and providing our own selection symbol for polygons.

        var fill = new SimpleFillSymbol("solid", null, new Color("#A4CE67"));

        var popup = new Popup({

            fillSymbol: fill,

            titleInBody: false

        }, domConstruct.create("div"));

        //Add the dark theme which is customized further in the <style> tag at the top of this page

        domClass.add(popup.domNode, "dark");

        map = new Map("map", {

          basemap: "gray",

          center: [-98.57, 39.82],

          zoom: 4,

          infoWindow: popup

        });

        var template = new PopupTemplate({

          title: "Boston Marathon 2013",

          description: "{STATE_NAME}:  {Percent_Fi} of starters finished",

          fieldInfos: [{ //define field infos so we can specify an alias

            fieldName: "Number_Ent",

            label: "Entrants"

          },{

            fieldName: "Number_Sta",

            label: "Starters"

          },{

            fieldName: "Number_Fin",

            label: "Finishers"

          }],

          mediaInfos:[{ //define the bar chart

            caption: "",

            type:"barchart",

            value:{

              theme: "Dollar",

              fields:["Number_Ent","Number_Sta","Number_Fin"]

            }

          }]

        });

        var featureLayer = new FeatureLayer("http://services.arcgis.com/V6ZHFr6zdgNZuVG0/arcgis/rest/services/Boston_Marathon/FeatureServer/0",{

          mode: FeatureLayer.MODE_ONDEMAND,

          outFields: ["*"],

          infoTemplate: template

        });

        map.addLayer(featureLayer);

       

        geocoder = new Geocoder({

          map: map,

          autoNavigate: false

        }, "search");

        geocoder.startup();

       

        on(geocoder, "find-results", function(results){

          console.info(results.results);

          var mpPt = results.results.results[0].feature.geometry;//new Point(-122, 45.6);

          var scrPt = map.toScreen(mpPt);

          map.emit("click", { bubbles: true, cancelable: true, screenPoint: scrPt, mapPoint: mpPt });

        });

      });

    </script>

  </head>

 

  <body class="claro">

    <div id="search"></div>

    <div id="map"></div>

  </body>

</html>

BrianO_keefe
Regular Contributor II

Okay Robert,

So I've modified /widgets/Geocoder/Widget.js : Line 239 as follows:

/widgets/Geocoder/Widget.js : Line 239

// First thing we need to do is convert the feature.geometry to a "mapPoint" object

var mpPt = feature.geometry;

// Once we have the "mapPoint" object we convert it to a "screenPoint" object

var scPt = this.map.toScreen(mpPt);

// The click event requires a screenpoint and a mappoint in order to fire.

// Now we fire that event.

this.map.emit( "click", { bubble: true, cancelable: true, screenPoint: scPt, mapPoint: mpPt } );

What I'm getting is a dual hit.

http://maps.cityoftulsa.org/jsdev/citycouncil/

If you type in an address, like mine, 4740 E 5th Pl in Tulsa, Ok it pops up two districts. But now that I'm zoomed in, if I do the same address search then I get just one. Ugh!

I wonder if zooming to that point FIRST would correct this situation.

0 Kudos
RobertScheitlin__GISP
MVP Esteemed Contributor

Brain,

  Using your site and that address I only get one district...

BrianO_keefe
Regular Contributor II

I don't have enough facepalms for this.

Thanks for testing it Robert...

I'm thinking that after I get this cleaned up and make a settings page this would be a great upgrade for the Geocoder.

But we are getting dual councils popup for various addresses.

When I check out the Screenpoint and Mappoint variables I'm getting some distinctly different looking coords.

  1. mpPt: Object
    1. spatialReference: Object
    2. type: "point"
    3. x: -10685928.332287207
    4. y: 4321245.409954926
    5. __proto__: Object
  2. scPt: Object
    1. spatialReference: undefined
    2. type: "point"
    3. x: -25248
    4. y: 2027
    5. __proto__: Object

I'm almost certain that my duplicate council issues are coming from the two points being registered.

Maybe if I zoomed first and the generated the scPt and mpPt?

I am looking around for how to zoom to a feature.geometry, so once I get that figured out I'll do that THEN run the mpPt and scPt and emit.

0 Kudos
RobertScheitlin__GISP
MVP Esteemed Contributor

Brain,

  Are you sure that the geocoded address is not returning two different locations? I would put:

console.info(content);

at line 239 and see if you are getting two results from the Geocoder

BrianO_keefe
Regular Contributor II

Great idea. I hadn't even considered that.

Just ran that code and I'm getting a single address.

Ugh!

0 Kudos
BrianO_keefe
Regular Contributor II

My Code

console.info(content); 
  // First thing we need to do is convert the feature.geometry to a "mapPoint" object  
  var mpPt = feature.geometry;
  console.log( "Map Point is set." );
  this.map.centerAndZoom(mpPt,16);
  console.log( "Center and Zoom" );
  // Once we have the "mapPoint" object we convert it to a "screenPoint" object
  var scPt = this.map.toScreen(mpPt);
  // The click event requires a screenpoint and a mappoint in order to fire.
  // Now we fire that event.
  // this.map.emit( "click", { bubble: true, cancelable: true, screenPoint: scPt, mapPoint: mpPt } );
  this.map.emit( "click", { bubble: true, cancelable: true, screenPoint: scPt, mapPoint: mpPt } )

0 Kudos
BrianO_keefe
Regular Contributor II

If I am already zoomed in to an area then the same address only gives me ONE Council...

But when zoomed out I get two for any address close to a border.

I was trying this on our Watershed map with similar results. Close to the border? Two results...

I had thought I could just adjust the bubble method to false, and fix it but I haven't read the documentation on it and it didn't do what I thought it did... lol...

0 Kudos