US and Worldwide: +1 (866) 660-7555
Page 1 of 3 123 LastLast
Results 1 to 10 of 25

Thread: newMapComponent - dynamic source for shape information?

  1. #1
    Join Date
    Sep 2014
    Posts
    12

    Default newMapComponent - dynamic source for shape information?

    The NewMapComponent for CDE is great, but it would be even better if we could get the list of shape information dynamically from a geodatabase, instead of a fixed KML file. Some KML files are too large, and without SQL queries would needlessly clog the application with unneeded data.

    Is there any way to do that?

  2. #2
    Join Date
    Jan 2014
    Posts
    186

    Post

    Hi stanasa,

    if the component is rendering markers instead of shapes, such a feature is already in place. It works by delegating the resolution of coordinates to an add-in.
    In other words, if the query contains human-friendly columns such as "City", "country", an http request is launched for every row, which will lookup the latitude and longitude dynamically.

    This approach is convenient for small data sets but has the drawback that it increases the time it takes to populate the map with data, as it becomes dependent on a service that may have a big lag. Nominatin, for instance, is a free service that limits the number of requests per second to about 1. So, if you have 30 markers, your map takes about 30 seconds to render.

    But your question is about shapes, and in that mode, the location resolving add-in is not invoked.
    While it might be a good idea to create a JIRA case to ask for this "add-in encapsulating a geo-shape resolving service" feature request, this does not solve your problem today.

    What could solve your problem is the hack I'm about to describe next (hack = it might stop working in the next CTools release).
    It violates the principle that business data and presentation data should be kept separate, but here it goes:

    1) augment your query with a third column containing a serialized list of coordinates, corresponding to the desired shape.

    For instance, if you choose to serialize using JSON.stringify, you would have a query that outputs something like:

    | key | value | shape
    -----------------------------
    | "US" | 100 | "[[[[19.33,-155.1], ...."
    | "CN" | 100 | "[[[[20.06,110.72], ...."


    2) In postFetch, build a dictionary containing the map key and the corresponding coordinates and assign them to the component "shapeDefinition" property:

    function f(json){

    this.shapeDefinition = _.chain( json.resultset ).map(function (row){
    return [row[0], JSON.parse(row[2]) ];
    }).object().value();

    return json;
    }


    Of course, you could also implement a synchronous ajax request that fetches the list of coordinates for each row, but that is a tad more complex thing to do.
    Last edited by crusso; 04-04-2015 at 05:53 AM.

  3. #3
    Join Date
    Sep 2014
    Posts
    12

    Default

    Thanks, crusso, I will give it a try and get back with an update.

  4. #4
    Join Date
    Feb 2017
    Posts
    20

    Default

    i tried this with newmapcomponent:

    map engine: openlayers
    operation mode: shapes
    tilesets to display as layers: default
    datasource: one datasource with:
    | key | value | shape
    -----------------------------
    | 1100015 | 100 | "[[[[19.33,-155.1], ...."
    | 1100023 | 100 | "[[[[20.06,110.72], ...."


    but there are no shapes in the map, any help?

    (sorry my bad english)

  5. #5
    Join Date
    Jan 2014
    Posts
    186

    Default

    Hi hugonr

    The solution I presented earlier was merely an outline of solution, not a fully tested solution. In fact, I did not test it at all.
    You simply should not expect random snippets to work immediately.
    Just keep in mind that sometimes the people replying to questions in this forum are merely human and not infallible gods.

    First of all did you paste the snippet of code into postFetch?
    If you did, and the code didn't work, are there any errors in the browser (web) console?
    What version of Pentaho or CDE are you using?
    That sort of information is useful. If you don't supply that information, then the code demi-gods have to guess why things don't work.

    Also, looking at the source code of NewMapComponent, it seems the snippet presented earlier will not work in Pentaho 7.0 and later.

    For Pentaho 7.0+, the approach must be via a "ShapeResolver" addIn.
    The addIn must iterate over each row to look up the string in the column "shape" and transform it to a GeoJSON object.
    It must also build a object whose keys are contents of the column "key", and whose values are the GeoJSON objects.
    This is not terribly complicated to do, but it takes more than 2 minutes to write and 15 minutes to test.
    Last edited by crusso; 05-28-2017 at 11:10 AM.

  6. #6
    Join Date
    Feb 2017
    Posts
    20

    Default

    thanks for the reply crusso!!!

    yes, this i need to work with this information, but i just got one kml file with all the data i need so now i will try with this file.

    i think will be better than using it from datasource.

    thanks!!!!!

  7. #7
    Join Date
    Feb 2017
    Posts
    20

    Default

    Hi Crusso!!!

    i will try again this aproach, here are the answers:

    First of all did you paste the snippet of code into postFetch?
    Yes, in postfetch
    function f(json){
    this.shapeDefinition = _.chain( json.resultset ).map(function (row){
    return [row[0], JSON.parse(row[2]) ];
    }).object().value();
    console.log(this);
    return json;
    }
    If you did, and the code didn't work, are there any errors in the browser (web) console?
    No, and my object now have the ShapeDefinition with the keys and coordinates
    observation: without the code in postfetch i dont have shapedefinitions

    What version of Pentaho or CDE are you using?
    Release 6.1.0.1.196

    I will really appreciate your help!!!

  8. #8
    Join Date
    Jan 2014
    Posts
    186

    Default

    You'll need the addIn.

    Upload the following as a .js file into PUC, and include it as a resource in your dashboard:
    Code:
    define([
      "cdf/AddIn",
      "cdf/Dashboard.Clean",
      "cdf/lib/jquery",
      "amd!cdf/lib/underscore"
    ], function(AddIn, Dashboard, $, _) {
      "use strict";
      var inlineGeoJson = {
        name: "inlineGeoJSON",
        label: "Inline GeoJSON shape resolver",
        defaults: {
          colIdx: null, //column index containing the json map definitions
          idPropertyName: "" //GeoJSON feature property that will be used to index the feature
        },
        implementation: function(tgt, st, opt) {
    
          var map = _.chain(st.tableData)
            .map(function(row, idx){
              return [
                st.ids[idx], polygonToGeoJson(row[opt.colIdx])
              ]
            })
            .object()
            .value();
    
          var deferred = $.Deferred();
          deferred.resolve(map);
          return deferred.promise();
        }
      };
    
    
      function polygonToGeoJson(coordinatesStr){
        return {
          type: "Feature",
          geometry: {
            type: "Polygon",
            coordinates: JSON.parse(coordinatesStr)
          }
        }
      }
    
    
      Dashboard.registerGlobalAddIn("NewMapComponent", "ShapeResolver", new AddIn(inlineGeoJson));
    
    
      return inlineGeoJson;
    });
    Then, in your map component, add the following in preExecution:

    Code:
    function(){
      this.shapeResolver = "inlineGeoJson";
      this.setAddInOptions("ShapeResolver", "inlineGeoJson", { colIdx: 2});
    }
    I did not test this. This should get you started, though.
    Last edited by crusso; 06-20-2017 at 02:08 PM. Reason: improved legibility

  9. #9
    Join Date
    Feb 2017
    Posts
    20

    Default

    The steps i did:

    1. in my PUC browse files i uploaded the file addinshape.js (with the addin code),
    2. i created one dashboard with the query of this post and one newmapcomponent with the configuration i did in the last one (see my reply of this post),
    3. in my PUC layout panel i added a resource (javascript/external file), and choose the addinshape.js,
    4. in my newmapcomponent i used that pre execution code.

    i tried with the postfetch and without it:
    function f(json){
    this.shapeDefinition = _.chain( json.resultset ).map(function (row){
    return [row[0], JSON.parse(row[2]) ];
    }).object().value();
    console.log(this);
    return json;
    }
    did not work, but its a start, i will study this solution better and will try it!

    thanks again crusso!!!!!!

  10. #10
    Join Date
    Jan 2014
    Posts
    186

    Default

    You should not need to add anything to postFetch.

    By the way, there was a glitch: it should be row[opt.colIdx] and not st.tableData[idx, opt.colIdx]) ...


Tags for this Thread

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •