Showing posts sorted by relevance for query google. Sort by date Show all posts
Showing posts sorted by relevance for query google. Sort by date Show all posts

Friday, April 10, 2009

GoogleAppEngine and BlazeDS

Google released a java version of the AppEngine. So I was very excited and wanted to see if I can host an application based on the Spring BlazeDS Integration framework. All was fine until I deployed the application and got a "Class Not Found" Exception. Looking at the log found the following: java.lang.management.ManagementFactory is a restricted class. Please see the Google App Engine developer's guide for more details. Check the docs and there is a list of "white-list" classes, and java.lang.management is not there :-(. Was so close! oh well, back to EC2 :-)

Sunday, December 20, 2009

Street View Within Flex API for AGS

There is this great sample in our code gallery where a Google Streetview is integrated with a map based on the Flex API for AGS. However, what I wanted is to have the street view to be part of the map, not an HTML sibling element. Found this project (flex-iframe) on google code, where you can display an HTML page inside a flex application. So I went ahead and merged the two projects. One of the requirements is to modify the template html file that is generated by Flex Builder with additional javascript code that enables the bridging between the flash and javascript world. I was not thrilled with fooling around with generated code, then I remembered the JavaScript flex tag by Abdul Qabiz. This flex element enables you to put javascript code _in_ a flex application, and on initialization it will be "evaled" and injected into the parent document DOM. So I merged all three projects together and this is you get. Check out it and tell me what you think. And like usual, the source code is here. There are some gems in there, like a custom symbol and I've adjusted the JavaScript flex tag. I've tried the app on my mac using safari, firefox and chrome, and it worked fine. However, I had issues with firefox on vista. IE worked for me.

Tuesday, October 11, 2011

Map Tiles For Offline Usage Using ArcGIS API for Flex

So… Google introduced an offline feature to their mobile mapping application, enabling you to view map tiles when you are disconnected from the network. This is pretty neat and very useful now that local storage is so “abundant” on mobile devices. In this post, I would like to show you how to use the mobile device local storage for offline tile retrieval using the ArcGIS API for Flex. When we built the API, we always had the vision of extensibility to enable people to do things that we did not think about. One of then was to enable the control of the URL from where the tiles will be retrieved. A while back, I did such an implementation using Amazon S3. So, I rehashed that code using Adobe AIR File capabilities. The demo application that I am featuring here operates in two modes; an online mode and an offline mode. In the online mode, I keep a set all downloaded tiles for a particular viewing session. Before I go offline, I download the map server metadata and all the visited tiles to my device local storage. The AIR runtime can notify an application when the network connectivity changes. This enables me to put the application in offline mode and when I start panning and zooming, rather than retrieving the tiles from the cloud, I retrieve the tiles from my local storage. Pretty neat, eh ? So here is the code:
public class OfflineTiledMapServiceLayer extends ArcGISTiledMapServiceLayer
{
  override protected function getTileURL(
     level:Number,
     row:Number,
     col:Number
  ):URLRequest
  {
    var urlRequest:URLRequest;

    if (Model.instance.isOffline)
    {
      urlRequest = new URLRequest(
        "app-storage:/l" + level + "r" + row + "c" + col);
    }
    else
    {
      urlRequest = super.getTileURL(level, row, col);
      if (urlRequest.url in Model.instance.cacheItemDict === false)
      {
        const item:CacheItem = new CacheItem();
        item.urlRequest = urlRequest;
        item.level = level;
        item.row = row;
        item.col = col;
        Model.instance.cacheItemDict[urlRequest.url] = item;
      }
   }

   return urlRequest;
 }
}
The OfflineTiledMapServiceLayer extends the ArcGISTiledMapServiceLayer class and overrides the getTileURL function. This function is invoked to get the tile URL for a particular map level, row and column. If the application mode is offline, then the “app-storage” url scheme is used and the path is in the form of “l”+level+”r”+row+”c”+column. If the application mode is online, then the super.getTileURL is invoked and we keep a set of visited URLs. Using the application settings view, the application has the option to download the map server metadata and iterate over the visited tiles and save the bitmap images to the local storage as defined by File.applicationStorageDirectory. The AIR runtime has the capability to notify the application of a network change. When this occurs, I ping a URL (www.google.com) using the HTTPService to determine if this is a connect or a disconnect change thus putting the application in an online or offline state.
The application can be written in such a way that any visited tile can automatically be saved to the local storage, I leave that as an exercise for the reader :-)
Like usual, all the source code is available here.
NOTE: This sample application is for demonstration purposes ONLY and is intended to be used with your own legally cacheable tiles - I am not a lawyer, but I am pretty sure that it is not legal to save locally the ArcGIS.com accessible tiles.

Friday, August 19, 2011

ArcGIS Lite API for Flex

The ArcGIS API for Flex is pretty amazing and very powerful, but it is very GIS centric. Flex Programmers have to know for example the difference between mercator and geographical coordinates systems and have to understand the concepts of map layers, etc….
Programmers just want to put dots on maps at a specific latitude and longitude. This is very easy to do say for example using the google map API and folks have been asking for something like that for a while. So, I am please to tell you about an open source project that we have launched on github that is exactly that. A simple mapping API that is based on the core API to enable Flex developers to build mapping applications. The idea to open source the project is to let you see how some high level functions are implemented using the low level API. Here is a quick sample:
<?xml version="1.0" encoding="utf-8"?>
<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009"
               xmlns:s="library://ns.adobe.com/flex/spark"
               xmlns:mx="library://ns.adobe.com/flex/mx"
               xmlns:views="com.esri.views.*">
    <fx:Script>
        <![CDATA[
            import com.esri.ags.events.MapEvent;

            private function map_loadHandler(event:MapEvent):void
            {
                map.setCenter([ 40.736072, -73.992062 ])
            }
        ]]>
    </fx:Script>
    <views:ESRIMap id="map" load="map_loadHandler(event)"/>
</s:Application>

In addition, the API is mobile friendly. You can build Android and iOS mapping applications using the Flex API. Here is a mobile sample:

<?xml version="1.0" encoding="utf-8"?>
<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009"
               xmlns:s="library://ns.adobe.com/flex/spark"
               xmlns:views="com.esri.views.*">
    <fx:Style source="stylesheet.css"/>
    <fx:Script>
        <![CDATA[
            import com.esri.ags.events.MapEvent;
            import com.esri.events.GeolocationUpdateEvent;

            private function map_geolocationUpdateHandler(event:GeolocationUpdateEvent):void
            {
                map.locationToAddress(event.mapPoint, 50.0);
            }

            private function map_loadHandler(event:MapEvent):void
            {
                map.whereAmI();
            }
        ]]>
    </fx:Script>
    <views:ESRIMobileMap id="map"
                         geolocationUpdate="map_geolocationUpdateHandler(event)"
                         load="map_loadHandler(event)"/>
</s:Application>

As mentioned earlier, the project is on github. So you can clone it, compile it with the core API swc and learn how geocoding or routing is implemented.

The project can use more documentation as, I do write self documenting code! LOL - Sorry, that was not funny since this is supposed to be a stepping stone to the core API that _is_ very well documented. So, I will have to spend more time on this and add more high level functions like “driveTimePolygon”.

Anyway, “git clone” the project and tell me what you think.

Want to give credit where credit is due - Andy Gup started this initiative with his great Starter Project Template.

Just to clarify an important point. This API is for very simple mapping purposes and is NOT maintained by the core team.

Wednesday, February 10, 2010

How Oracle Can Improve Java

Found this great article "15 Ways Oracle Can Make Java Better (and Improve Its Stance with Developers)" - here is my "in the weed" take:
  1. Keep JavaONE - with heavy focus on developers.
  2. Embrace OSGi down in the core VM.
  3. Kill JavaFx - Work closer with Adobe on Flex / BlazeDS / LCDS.
  4. Improve Dynamic Language Support - groovy / scala / JRuby / Jython /etc...
  5. Talk to Google about ME (seriously?) / Android
  6. Kill NetBeans - Eclipse may be King, but IntelliJ is God !
  7. Introduce new language primitives XML / Function / JSON.
  8. Improve language - set/get bean, native String ( switch myString {case "foo": ...}) as for casting.
  9. LINQ for Java - LCDS can help here.
  10. Talk to the Spring folks - there-is-only-one-framework-zuul :-)
  11. No "Effing" store !
So....what do you think ?

Thursday, May 28, 2009

Mapping EXIF Images With GPS Info

Was tasked to load an EXIF image with GPS info onto a map using the Flex API for AGS. So I first looked around for existing AS3 libraries and found ExifInfo. Downloaded it and tried it, but somehow it failed loading some EXIF images. Then I remembered a JavaScript library that a colleague pointed it out to me. So I ported the code to AS3 (optimization will come later) and here is the result. I used picasa to load some images and geo-tagged them using Google Earth (that is from the Tools menu BTW) and it worked pretty well. I borrowed some ideas and code from the author of ExifInfo and made my own EXIF mxml enabled class. Like usual here is the source code. BTW - There is a TextInput field at the bottom of the application, enter the url of your image (make sure that you have a crossdomain.xml at the base of your url) and if the image has EXIF GPS info, the map will display it. Try "assets/sample1.jpg" and hit enter.

Tuesday, August 26, 2008

Heat Map + Papervision3D

Doug McCune (one of my all time Flex heroes) contributed heavily to SpatialKey, which looks and works great. Got to see it last week at 360|Flex in San Jose. I've been wanting to do something similar, but in 3D! Dabbled a bit with Papervision3D, but wanted to get into it, and that was the perfect opportunity. The idea that I had was to read a country shapefile, and thematically map all the cities in that country based on some attribute. And do all that on the client using Flex. I did a little bit of research, and here is a list of sites that "inspired" me:
And here is a snapshot of the result:


You can download the source code of the application from here. And you can see a sample demo here.

Sunday, April 10, 2016

Vector Tiles: The Third Wave

When it comes to web mapping, we are surfing on a third wave in our digital ocean. And the “collaborative processing” between the digital entities while surfing that wave is making the ride more fun, insightful and expressive.

The first web wave was back in the mid 1990s, where interactive maps in the form of html image tags relied heavily on the server and requests parameters to regenerate the image when you clicked on the edge arrows to pan and zoom. Remember MapQuest and ArcIMS ?

Then in the mid 2000s came the second wave or more like a tsunami, Google Maps. You hold down the right mouse button on the map and drag to pan, you use the scroll wheel to zoom in and out, and… when you click on the map, a bubble appears on the map showing the details of the clicked location. Disruptive ! And all was smooth, responsive and AJAXy. This is when I believe that this collaborative processing concept took root and materialized itself in the web mappers’ minds. Soon after, more expressiveness was required as HTML was lacking in power and functionalities and the capitalization on browser plugins emerged to create Single Page Applications. Remember Flex and Silverlight ?

We are now in the mid 2010s. Flash is dead because he ate an “Apple”. HTML5, CSS3 and Javascript are in full swing and though Tile Services are fast as the tile images are preprocessed and prepared to be displayed, they are still image based, and dynamic styling of the features in a tile is not easy. In addition, with the ubiquity of GPUs on edge devices, faster rendering for expressiveness is now possible through the elusive “collaborative processing”.

Enter Vector Tiles. Map box has defined a vector tile specification that we at Esri have adopted it in our Javascript API, and demonstrated its versatility at the 2015 User Conference. Andrew Turner has a nice writeup about it. And found this nice in-depth paper that analyses the dynamic rendering of vector-based maps with WebGL.

I wanted to know more about it and I learn by doing. So I implemented two projects, a Mapbox Vector Tile encoder and a visualizer as heuristic experiments to be used with the Esri Javascript API. Again, these are experiments and will report on more updates.

Sunday, January 28, 2024

Arabic SDK For Apache Spark

I recently attended the Esri Saudi Arabia User Conference and was amazed by the changes in the Kingdom. The capital city of Riyadh is booming and proliferating. During the conference, I presented on integrating GenerativeAI and GIS in the plenary session and led a session on BigData and GeoAnalytics Engine. GeoAnalytics Engine, based on Apache Spark, allows spatial operations on Spark data frames. We showcased a project called "A Day in the Life," which used historical traffic data from HERE to demonstrate traffic congestion during peak hours. Traffic is notoriously bad in the city, so this was a fitting example. My colleague Mahmoud H. presented a traditional workflow process in a Jupyter Notebook off a Google Cloud DataProc cluster, efficiently processing over 300 million records (this is relatively "small"). The processed traffic information was then displayed in ArcGIS Pro in a time-aware layer to reflect the congestion visually while activating a time slider. At the end of the presentation, we surprised the audience by using ChatGPT to translate Arabic sentences to SparkSQL code, and Azure OpenAI GPT4 handled the translation very well. Look here for code snippets. This form of interaction IS the future, and I am excited to invest more in this technology and in the following areas:

  1. Enhanced Visualization and Real-time Data Integration:
    • Dynamic Visualization: Integrating real-time traffic data feeds into existing models. This will not only show historical congestion but also provide live updates. Dynamic heatmaps can be particularly effective in visualizing the intensity of traffic at different times.
    • 3D Modeling: Utilize ArcGIS's 3D scene capabilities to give a more immersive view of traffic congestion and urban planning scenarios.
  1. Improved Data Analysis through Machine Learning:
    • Predictive Analytics: Integrate machine learning models to predict future traffic patterns based on historical data, weather conditions, events, and other variables.
    • Anomaly Detection: Implement anomaly detection algorithms to identify unusual traffic patterns, which can be crucial for incident response and urban planning.
  1. Enhancing User Interaction and Accessibility:
    • Multilingual Support: While we showcased the translation of Arabic sentences to SparkSQL code, we should consider expanding this feature to include more languages, making your tool more accessible to a global audience.
    • Voice Commands and Chatbots: Integrate voice command functionality and develop a chatbot using Azure OpenAI GPT4 for querying and controlling the GeoAnalytics Engine, making the system more interactive and user-friendly.
  1. Scalability and Performance Optimization:
    • Optimization for Large Datasets: Continue to refine the efficiency of processing large datasets. Explore the latest advancements in distributed computing and in-memory processing to handle even larger datasets more efficiently.
    • Cloud Integration: Ensure the solutions are cloud-agnostic and can be deployed on any public or private cloud provider, enhancing the system's scalability and reliability.
  1. Collaboration and Sharing:
    • Collaborative Features: Develop features that allow multiple users to work on the same project simultaneously, including version control and change tracking for shared projects.
    • Export and Sharing Options: Enhance the ability to export results and visualizations in various formats and share them across different platforms, facilitating easier collaboration and reporting.
  1. Ethical Considerations and Transparency:
    • Data Privacy: Address data privacy concerns by implementing robust data encryption and anonymization techniques, ensuring that individual privacy is respected while analyzing traffic patterns.
    • Algorithm Transparency: Provide clear documentation and explanations of the algorithms used, promoting transparency and trust in your system.

Tuesday, October 11, 2011

Yet Another Micro Architecture for Flex RIA and RMA

The Holistic micro-architecture framework for building RIAs and RMAs (Rich Mobile Applications) "borrows" from Robotlegs, PureMVC, Cairngorm, SWIZAS3Signals and the SpringFramework. Each has one or two things that I really like about it, but what I wanted is to bring all these things into one simple, very lightweight framework that enables me to quickly and more importantly methodically build mobile, web and desktop applications. This Holistic API is designed to work on top of either the Flex web or mobile framework and takes advantage of the Flex compiler, environment and lifecycle. Several "design patterns" are utilized in the API, such as Model-View-Controller, Loose Coupling, Locator, Usage of Interface, Delegation, Dependency Injection, Separation of Concerns and Inversion Of Control, not sure if some of latter are pure design patterns per GoF, but bear with me :-) One thing that is heavily relied on, is programming to convention versus programming to configuration.

MVC

Looking at the above diagram, the state of an application resides in the Model. The model is a set of non visual properties, where some properties are annotated using the [Bindable] metadata, in such that a change event will be dispatched whenever that property is mutated. This [Bindable] metadata is an indication that this property is represented by a view.
public class Model {
    [Bindable]
    public var text:String;
}
Views are subclasses of UIComponents and are bound using curly braces (I call them 'magic' braces) to the Model to represent the state of the application based on the view capabilities.
<s:label text="{model.text}"/>
In the above example, this Label instance is representing the model 'text' property and any changes to the 'text' value will be auto-magically shown in the label location on the screen. For a more complex example; a property that is a list of features can be bound to a map view and the features will be drawn as points on the map. At the same time, that same list can be bound to a data grid where each feature will be represented as a row in that grid. A model can have multiple view representations in an application.
Now, if a view wants to modify the model, it does so using a controller. A view is not, I repeat, is not allowed to mutate the model. Only a controller is allowed to mutate the model. This is very important as a convention. All the logic to mutate the model should reside in a controller even if it means that the logic is a single line implementation. Trust me on this, when developing the application, in the beginning this might be a single line. But... along the application development process, this will get more elaborated per the application requirements. You will be tempted by the programming devils to "touch" the model from the view and you will come to regret it later on. So be resilient and do the right thing !
Enough preaching. So how does a view tell a controller to mutate the model ? Simple, using signals. A signal is a glorified event with integrated event dispatching enabling a loose coupling between the view and the controller.
The following is the signature of the static 'send' function in the Signal class:
public static function send(type:String,...args):void
The first required string argument is the signal type. This string is very important in our convention over configuration design as we will see later on. A signal can optionally carry additional information such as in the following example:
<s:textinput id="ti"/>
<s:button click="Signal.send('submit',ti.text)" label="{model.text}"/>
When the user clicks on the Button instance, a signal of type 'submit' is sent along with the text that was entered in the TextInput instance.
Now, I need 'something' to receive that signal and act on it. This something is a controller. Again, relying on convention over configuration, I will create a controller named 'SubmitController'. Note the prefix 'Submit', it is the same as the signal type. Again this is the convention over configuration that is working in my favor where by writing pseudo-self documenting code. I can look at my list of controllers in my IDE and can tell immediately from the names what signal is handled by what class. Yes, I will have a lot of controllers, but this divide and conquer approach enables me to do one thing and one thing very well and separate my concerns.
In the controller class implementation, to handle the 'submit' signal, I should and must have a function named 'submit' that accepts one argument of type String like the following:
[Signal]
public function submit(text:String):void
{
  ...
}
Note the [Signal] metadata on the function declaration. See, as a Flex developer, you are already familiar with and using the built-in annotations such as [Bindable]. But Flex enables a developer to create his/her own metadata that will be attached to the class in question for introspection, cool, eh ? Back to signals, one more example to solidify the association of signals to controllers - if you send a signal of the form:
Signal.send('foo', 123, 'text', new Date());
To handle that signal, you should have the following controller declaration:
public class FooController {
    [Signal]
    public function foo( nume:Number, text:String, now:Date):void {
      ...
    }
}
Note that the order of the handler function arguments should match the order and type of the signal arguments. 123 -> nume, 'text' -> text, new Date() -> now. What makes this pretty neat is the independence of the hardwiring signal dispatching mechanism and the handler is just a function that can be unit tested, more on that later.
Applications need to communicate with the outside world, say for example you want to locate an address using an in-the-cloud-locator service. Controllers do not communicate with the outside world, they delegate that external communication to a service. That service will use the correct protocol and payload format to talk to the external service be SOAP, REST, RemoteService in XML, JSON or AMF or whatever. To enable different implementations of these protocols, an interface is declared and is injected into the controller for usage like as follows:
public class LocateController {

    [Inject]
    public var locateService:ILocateService;

    [Signal]
    public function locate(address:String):void
    {
        locateService.locate(address,
            new AsyncResponder(resultHandler, faultHandler));
    }
}
The locateService variable is assigned at runtime using inversion of control and when the 'locate' signal is sent, it is handled by the 'locate' function who delegates it to the ILocateService implementation. The [Inject] metadata is for more than injecting service implementations. Here is another usage to overcome AS3 language constraints and make your code more testable. Say you start a project and Signal A is sent, you go and you write Controller A to handle the signal. Now you have to write another controller B to handle signal B (remember SoC :-) but you find that Controller A and B will share some code. Since you are a good OO developer, you create a super class S that has the common code and make Controller A and Controller B subclass S. You feeling pretty good, onto Controller C to handle signal C. But wait a minute, some code from Controller B can be shared with Controller C. Ok, you create a super class D and subclass. But wait a minute..., AS3 is a single inheritance model, than means Controller B cannot subclass super class S and D at the same time. This is where composition is better that inheritance where now I can move the common code to class S and class D and inject those classes into controller A,B and C.
public class AController {
    [Inject]
    public var refS:ClassS;

    [Signal]
    public function doA(val:*):void {
        refS.doS(val);
    }
}

public class BController {
    [Inject]
    public var refD:ClassD;
    
    [Inject]
    public var refS:ClassS;

    [Signal]
    public function doB(val:*):void {
        refS.doS(val);
        refD.doD(val);
    }
}

public class CController {
    [Inject]
    public var refD:ClassD;

    [Signal]
    public function doC(val:*):void {
        refD.doD(val);
    }
}
Cool ? Onward, something _has_ to wire all these pieces together and that something is a Registry instance that is declared in the main application mxml as follows:
<fx:Declarations>
    <h:Registry id="registry">
        ...
   </h:Registry>
</fx:Declarations>
The children of the Registry are all the application controllers and all injectable delegates and services. So using the above example:
<h:Registry id="registry">
   <m:Model/>
    <c:ClassS/>
    <c:ClassD/>
    <s:AController/>
    <s:BController/>
    <s:CController/>
</h:Registry>
Taking advantage of the declarative nature of Flex, I declare the registry children that gets translated into ActionScript instantiation, whereupon creation completion, the registry will introspect each child for [Inject] metadata and invokes the setter with the appropriate type instances. Next, the [Signal] metadata are located and a proxy object is created wrapping the annotated function as event listener to the Signals (remember, signals are nothing more than glorified events). All this introspection by the Registry is perform using the as3-commons-reflect library (url). Going back to programing to interfaces and having multiple implementation of an interface in the Registry, how is the injection resolved ? Well, by default the first implementation is injected. But what if I want a specific implementation ? here is the solution:

<h:Registry>
    <c:RestService/>
    <c:SoapService id="soapService"/>
    <c:FooController/>
    <c:BarController/>
</h:Registry>

[Register(name="restService")]
public class RestService Implements IService {
  ...
}

public class FooController {
  [Inject]
  public var restService:IService;
  ...
}

public class BarController {
  [Inject(name="soapService")]
  public var service:IService;
  ...
}

There is a lot packed in this example and there is a lot of conventions, so stay with me. The registry is declared with a couple of services and controllers. Note that the SoapController is registered with the "soapController" id. This enables the BarController to be injected with that specific implementation of the IService interface via the name attribute in the inject metadata. Next, the RestService is registered with the Registry with the name "restService" as declared in the class metadata. Now (magic time), the FooController is injected with the RestService instance despite the absence of the name attribute in the inject metadata because the _variable_ name is same as the class registration. Pretty powerful, I know, mind blowing!

Ok, last but not least, unit testing. Actually, if you do TDD, that should be first. The holistic framework looks for simple interfaces, classes and functions, and with the built-in capabilities of unit testing and code coverage add-on to FlashBuilder, there is no excuse not to test your code. Whole books and articles have been written about Flex unit testing so google them.

Like usual all the source code is available here. I drink my own champagne, what you will find is the Flex unit test project that includes the holistic library.

Have fun.

Update: I created a very simple project that demonstrated the usage of the Holistic framework. As I said it is a simple application that displays a data grid that is bound to a list property in the model. Below the grid is a form that enables you to enter a first name and last name. When you click on the submit button, a signal is sent with the entered info. A handler will received the info and will delegate it to a service that uppercases the values and adds them to the list.

Tuesday, March 20, 2012

DnD File using HTML5 into Flex Web App

So….I always wanted to Drag and Drop an external file into a Flex application running in the browser. Well.. you can use the FileReference API to browse and load a file, but I really wanted to DnD. Unfortunately, this is not allowed due to security constraints of the Flash Player. However, using the latest proposed W3C DnD API and the File API, I should be able to use the last two and the AS3 ExternalInterface API to accomplish what I want. So, here is the content of a simple xml file that I would like to DnD and render on a map:
<markers>
    <marker x="45" y="45" label="M 1" info="This is M1"/>
    <marker x="-45" y="-45" label="M 2" info="This is M2"/>
</markers>
I modified the HTML wrapper to use the JavaScript DnD and File API (if available) to listening for “dragenter”, “dragover” and “drop” events on the FlashPlayer container.
var DnD = {
loadHandler:function () {
  var dropContainer = document.getElementById("DnDApp");
  dropContainer.addEventListener("dragenter", function (event) {
    event.stopPropagation();
    event.preventDefault();
  }, false);
  dropContainer.addEventListener("dragover", function (event) {
    event.stopPropagation();
    event.preventDefault();
    event.dataTransfer.dropEffect = 'copy';
  }, false);
  dropContainer.addEventListener("drop", function (event) {
    event.stopPropagation();
    event.preventDefault();
    var files = event.dataTransfer.files, len = files.length;
    for (var i = 0; i < len; i++) {
      var file = files[i];
      var fileReader = new FileReader();
      fileReader.onload = function (event) {
        dndApp.drop(event.target.result);
      }
      fileReader.readAsText(file);
    }
  }, false);
}
};
if( window.File && window.FileReader){
  window.addEventListener("load", DnD.loadHandler, false);
} else {
  alert('Your browser does not support File/FileReader !');
}
On dragenter, I stop the event propagation and prevent the default behavior. On dragover, I do the same and in addition, I update the drop effect to show a “+” icon over the drop area. And finally, on drop, I iterate over the list of dropped files, whereupon I read as text each file using the FileReader API. When the file is read (remember, this is all asynchronous), I hand over the content to the Flex application. On creation completion of the Flex application, the “drop” callback is registered using the EternalInterface enabling the host javascript wrapper to invoke the internal dropHandler function.
private function this_creationCompleteHandler(event:FlexEvent):void
{
  ExternalInterface.call("setObjectID",
    ExternalInterface.objectID);
  ExternalInterface.addCallback("drop", dropHandler);
}

private function dropHandler(text:String):void
{
  const doc:XML = new XML(text);
  for each (var markerXML:XML in doc.marker)
  {
    const mapPoint:MapPoint = new WebMercatorMapPoint(
      markerXML.@x,
      markerXML.@y);
    arrcol.addItem(new Graphic(
      mapPoint,
      null, {
        label: markerXML.@label,
        info: markerXML.@info }));
  }
}
The latter accepts a String argument that is converted into an XML instance, and using E4X, each child marker element is converted to a Graphic that is added to a graphic layer graphic provider array collection. Cool, eh ? Note that the graphic layer has it infoWindowRenderer property defined, is such a way that if you click on any of its graphics, a info window content will be displayed whose content is an instance of the defined component. Like usual all the source code is available here. Have fun DnD’ing.
You can see the application in action by download the markers.xml file, and drag and drop it on the application running here.
PS: As of this writing, the two JS APIs work in Google Chrome 16 and later, Firefox 3.6 and later, Safari 6 will support the standard File API and our favorite (Not!) Internet Explorer 10 (Preview 2+). One of these days, will come back to this and use something like Dojo DnD to abstract me from all this - that will be a nice post!

Monday, December 1, 2008

Geolocation using Gears and Geode

Location based Services applications are requiring more and more that the geographical coordinates (or at least the neighborhood) of the user be automatically detected to create a more seamless and streamlined experience. Google Gears with its geolocation API and Mozilla Labs with its Geode project are making the W3C geolocation specification a reality. With such democratization of services, it would be nice to have geolocation as a native function in the flash player, so would be a JSON parser (but that is a topic of conversation for another day). Until then, we have to rely on the browser's capabilities to feed that information into the player. This can easily achieved using the ExternalInterface class. In this post, I adopted the geolocation W3C specification and implemented an ActionScript class to wrap the Gears and Geode javascript functions so they can be invoked from a Flex application. Make sure to install Gears and/or Geode to test this application. Using FlexBuilder, the index.template.html has to be adjusted to include the gears_init.js file and the geolocation.js wrapper file as follows:

...
<script type="text/javascript" src="AC_OETags.js"></script>
<script type="text/javascript" src="gears_init.js"></script>
<script type="text/javascript" src="geolocation.js"></script>
<style>
...

The registration of the callback functions is done by creating an instance of the GeoLocation class:

...
<geolocation:GeoLocation id="geolocation"/>
...

The position of the web application can be determined using something of the form:

...
geolocation.getCurrentPosition( currentPositionSuccessHandler, currentPositionFaultHandler );
...

Check out the application here. And like usual, you can download the source from here.

Tuesday, March 9, 2010

Augmented Reality, iPhone and ArcGIS Server

I am a HUGE fan of Augmented Reality, and one of my favorite applications on the iPhone is Layar. In this post, I will "walk you" through how to setup a simple ArcGIS Layar Point Of Interests (POI) layer and how to expose it through the iPhone application. In addition, I created a small Flex application that will enable you to add POIs to that feature class through a python geo-processor task.

BTW - this is heavily geared to using ESRI desktop and server tools and I'm assuming that you are familiar with these tools.

First, request a developer key from http://dev.layar.com/. This might take a couple of hours to get to you.

So, in the meantime, let's get started. Using ArcCatalog, create a new point feature class called 'Layar' in a geodatabase with the following fields: Title (text), Line2 (Text), Line3 (Text), Line4 (Text), Attribution (Text), Type (Integer), ImageUrl (Text:512).


Import that layer into a map document using ArcMap. Save and publish the MXD as a Map Service. Just to be on the safe side, clear your REST endpoint service directory cache and list the available services. You should now see the new map service and you can now query using REST the newly created 'Layar' layer.

Next, we need to populate this 'Layar' layer. With the Advent of ArcGIS 10, this could easily be achieved using the new FeatureTask endpoint. However, I'm still using a 9.3.X server and I will have to rely on a geoprocessing task to add point features to the Layar feature class. For the sake of simplicity and quick deployment, I decided to implement this GP task using python. So, using ArcCatalog, create a new GP Toolbox and add to the toolbox a new python script. You can download the script from here. Again, I'm assuming that you are familiar with all these tools. This script will have two parameters. The first input parameter should be named 'featureSet' of type 'FeatureSet' and its schema should reference the Layar feature class. The second parameter should be named 'objectID'. It has an output direction and is of type LONG. Basically what the script does; it expects a feature set with one feature. That feature is read using a cursor and placed in memory. Next an insert cursor is created on the Layar feature class and populated with the in memory information and executed. Upon a successful execution, the OBJECTID of the last inserted feature is retrieved and returned back as a parameter. The whole script is surrounded by a try: except: in case of an exception, where a -1 as an OBJECTID value is returned back. Simple but not simplistic :-) Publish this Toolbox, clear the cache and now you should have new GPService task.

To use this GP task interactively, I created a Flex based web application.
This application consists of a side-by-side map and form component enabling the user by zooming and panning to click and define POI coordinates and to populate that POI attributes. By clicking the Save button, the above publish GP task is invoked and upon a successful completion, the map is refreshed to show the newly added POI. The Flex application source code can be downloaded from here.

Now that we have created and authored this Layar information, we need to publish and consume it on the iPhone Layar application. The Layar folks have described in detail the JSON publishing format - http://layar.pbworks.com/GetPointsOfInterest. So what we need now, is a middleware that accepts an HTTP request from an iPhone, convert the input parameters to an ArcGIS REST query, invoke a query task whose URL is the Layar layer URL in the above publish map service, read the ArcGIS JSON response and convert to a Layar JSON response. Easy, eh ? That is why we have computers :-) I accomplished all this using Java Web Application - you can download the source code from here. This web application is basically a servlet that relies on the Apache HTTPClient library for http communication and the Jackson JSON processor library for fast consumption and JSON production. You might wonder why I decided to write this in Java versus say python. well...First, I'm a Java nut. Two, I can whip this up fairly quickly, Three, wanted to experiment with Google Java App Engine so I can be "in the cloud man !" - LOL, last one is just an artifact of the first two - but it is cool ! When the iPhone Layar application requests POI, it does so on a predefined URL (more on this later) with the following HTTP GET parameters, lat: your current latitude location, lon: your current longitude location, radius: the search radius in meters plus other parameters. In this application I'm just decoding lat, lon and radius.

Now that you have an in-the-cloud POI Layar endpoint and assuming that you have gotten your Layar developer key, you can sign in to http://dev.layar.com/ and create your own layer. The form will request a POI URL, enter your in-the-cloud poi servlet endpoint. All of the above was leading this point. I highly recommend that you test your layer using the Layar test page http://dev.layar.com/api20test/layarTestPage/.

To test this on your iPhone, go to "Settings" add add your developer ID and key to the Layar application settings. Launch the Layar application, and you should see your newly published layer.


This is just the tip of the iceberg. There is so much more that you can do, adjust and customize. I just wanted to share this "little" experience with you. Hope you found it useful and tell me what you think.

Monday, January 1, 2018

On ML and Elastic Principle Graphs

Happy 2018 all. It has been a while since my last post. Thank you for your patience dear reader. Like usual, the perpetual resolutions for every year in addition to blogging more are to eat well, often exercise and climb Ventoux.

Onward.

I genuinely believe that 2018 will be the year of the ubiquity of Geo-AI. It will be the year when Machine Learning and Spatial Awareness will blossom inside and mostly outside the GIS community.

We at Esri have had Machine Learning based tools in our "shed" for a long time. Every time an ArcGIS user performs a graphically weighted regression, trains a random trees classifier or detects an emerging hot spot, that user is using a form of Machine Learning without knowing it!

So one of my "missions" for 2018, it to make this knowledge more explicit to our users and non-traditional GIS users. Also, start to implement new forms of Machine Learning.

Machine Learning (ML), a branch of Artificial Intelligence (AI), is a disruptive force that is changing how today's industries are gaining new insight from their data. ML uses math, statistics and probability to find hidden patterns and make predictions from the data without being explicitly programmed. It is this last statement that is disruptive, "No explicit programming"! An ML algorithm iterates "intelligently" over the data, and the patterns emerge. Being iterative, the more data an ML algorithm is exposed to, the more refined the output becomes. Thus the coupling of BigData and ML is a perfect marriage fueled by cheap storage, ever more powerful computational power (think GPU) and faster networking.

This reemergence of this "No Explicit Programming" paradigm such as Deep Learning, Reinforcement Learning, and Self Organization is skyrocketing the likes of Google's AlphaGo-Zero, Facebook, and Uber.

So, I am starting this launch with something I have been fascinated by for quite some time, and that is "Elastic Principle Graphs."

It is a "deep" extension of PCA that I came across it during my research of mapping noisy 2D data to a curve and was fascinated by its self-organization.

img-alternative-text

After reading, (and rereading for the nth time) this paper, this GitHub repo is a minimalist implementation in Scala.

Happy New Year All.