Friday, December 30, 2011

ESRI ArcGIS and websockets (XSockets) with Microsoft Kinect Beta 2 SDK

Connected the dots... combined yesterdays ArcGIS and kinect demo with my earlier ArcGIS and web sockets demo:





Merging these together makes it possible to update the extent of the ArcGIS API for JavaScript clients by making gestures in-front of the kinect device that is connected to the ArcGIS API for WPF application, the communication between the clients are made through web sockets and for that I've used XSockets:

Thursday, December 29, 2011

Using Kinect and ArcGIS for WPF

Integrated Kinect SDK Beta 2 with ArcGIS for WPF 2.3 to see how it's possible to control an application for map viewing using the kinect sensors.

Tested gesture detection using KinectToolbox and Microsoft Speech Platform SDK.

Made two demos, one panning using gesture detection:



The other demo using my voice to control panning and zooming:







Saturday, December 17, 2011

Silent installer using Nullsoft Scriptable Install System (NSIS)

When making installers it's important to make it possible to run the installer silently. This is a requirement if you want to include your installer in another installer. I've inherited some installers on my new job, these were made in Nullsoft Scriptable Install System (NSIS). We have a requirement to include several application installers into a package to make the installation easier for the end users, so I've looked into what needs to be done in NSIS to make the installers silent.

It turns out to be quite easy, see the chapter on silent installer/uninstaller in the documentation, all MessageBoxes in the script has the possibility to have a /SD parameter where you can set the default return value if the installer is running in silent mode /S. To reduce cluttering the start menu with uninstaller links it's possible to use the IfSilent statement to jump over the creation of uninstall links.

Friday, December 09, 2011

Testing WebSocket support in ASP.Net 4.5

I've followed the descriptions in Paul Batum blog post Getting started with WebSockets in the Windows 8 developer preview  to test websockets in ASP.Net 4.5. Notice that you can use the Express version of Microsoft Visual Studio 2011 to run the WebSockets samples. Also see the Building real-time web apps with WebSockets using IIS, ASP.NET and WCF session from the Build conference. The samples seems to working correctly, so I will try to port my XSocket with Esri ArcGIS for JavaScript demo to ASP.Net.


Sunday, October 16, 2011

error : The Web Application Project BasicAspNetChat is configured to use IIS. Unable to access the IIS metabase. You do not have sufficient privilege to access IIS web sites on your machine.

Got this error:
error : The Web Application Project  is configured to use IIS. Unable to access the IIS metabase. You do not have sufficient privilege to access IIS web sites on your machine.

Resolution: 
Restart Visual Studio 2011 and run as administrator.

Sunday, October 02, 2011

CodeCamp, Map collaboration using XSockets with ArcGIS For Javascript

This weekend I've been to the XSockets CodeCamp i Sundsvall Sweden. Listening to Magnus Thor and Ulf Björklund talking about XSockets that is a websocket server that can be used to create real time web applications.

Robert Friberg held an interesting talk about liveDB an in-memory database that can be used to speed up development and handle high load applications. Basically hack away in .Net and you don't need any OR-mapper to work with the data storage.

But we did more then just listening, almost the whole Friday night was used to do hands-on coding with XSockets. My group made stunning demos for a real time soccer result live feeds web application. On Saturday I decided to use my GIS knowledge to try something different, so I hacked away on making a realtime map extent update application using ArcGIS for Javascript API. The result can be seen in this youtube clip. I will update this blog post with the details as soon as can, so stay tuned..


Step by step description on how to set up the project:

First create a project in VS2010. I create a MVC3 web project:


Create using empty template:


Use NuGet to get XSockets package:

>Install-Package XSockets



It adds resources to our project and create two projects for the XSockets server.


Create a html page in the root of the web application project:


I copy some boilerplate code from the show extent sample to the html page replacing the default code and added the web sockets code, so add the code below into your file:






Add a new handler using Scaffolding by writing:

>Scaffold XSocketHandler MyDemoHandler MyDemoClass



This creates a new strongly typed XSocketHandler in the XSocketHandler project:

Add code that returns the extent back to the other clients:


Do rebuild solution and check so there are no build errors.

Start the XMaxiSocketServer by right clicking the project and choose:
Debug | Start new instance

Choose allow when firewall ask this:



Open the MapClient.html page by right clicking the file choosing:
View in browser (should work if you have a web socket enabled browser Crome/Safari)

Answer no on the question:
And yes on the question:




Copy the address and start a new browser, when panning and zooming the maps in one browser it  should follow on the other browser, see youtube clip.


















Saturday, September 24, 2011

How to set up ArcGIS for WPF with Prism.

Got a question on the Testing ArcGIS for WPF + Funbeat + Prism. blog post if I could share the code. Sure thing! I've added a project for the sample code on google projects hosting https://code.google.com/p/arcgis-samples/ . I've removed the Funbeat APIs from the solution because it only adds to the complexity and probably only make sense for people in Sweden. 

Here is a step by step description on how I set up the project:
1. Shell app
Create a Wpf Application

1.1 Install Prism using NuGet
Use NuGet  to install microsoft Prism dependencies into the project:
Install-Package prism

1.1.1 Install Extensions using NuGet
Do the same for the extension to be used to load modules:

Install-Package Prism.UnityExtensions
Or
Install-Package Prism.MefExtensions

1.2 Rename MainWindow
Rename MainWindow to Shell both filename and class name, use refactor to rename class so that the partial classes get renamed as well.


1.3 Add region in Shell.xaml
xmlns:prism="http://www.codeplex.com/prism"
 
           
               
                   
               

           

       

1.4 Add Bootstrapper
Add a class Bootstrapper.cs to the project:


Add using:


using System.Windows;
using Microsoft.Practices.Prism.Modularity;
using Microsoft.Practices.Prism.UnityExtensions;
using Microsoft.Practices.Unity;
The bootstrapper should inherit from the UnitBootstrapper if it is the Unity extension you are using:
: UnityBootstrapper
 
 
 
Override methods as shown below:
 
protected override DependencyObject CreateShell()
{
    return new Shell();
}
protected override void InitializeShell()
{
    base.InitializeShell();
    App.Current.MainWindow = (Window)this.Shell;
    App.Current.MainWindow.Show();
}
protected override void ConfigureModuleCatalog()
{
    base.ConfigureModuleCatalog();
}

1.5 App.cs
Change the App.cs so that the Bootstrapper gets called:
protected override void OnStartup(StartupEventArgs e) {
base.OnStartup(e);
Bootstrapper bootstrapper = new Bootstrapper();
bootstrapper.Run();
}
1.6 App.xaml
The bootstrapper is now doing the job remove StartupUri in App.xaml:
StartupUri="MainWindow.xaml"

2. Module
Create a new project for the MapModule.
2.1 Install Prism using NuGet
Install-Package prism
2.1.1 Extensions
Install-Package Prism.UnityExtensions
Or
Install-Package Prism.MefExtensions
2.2 Add references
PresentationCore.dll
PresentationFramework.dll
WindowsBase.dll
System.Xaml.dll
2.3 Rename Class1

Class1 to MapModule
2.4 Add code to MapModule
Add using:

using Microsoft.Practices.Prism.Modularity;
 
Let MapModule inherit IModule:
: IModule
public void Initialize()
{
}
2.4.1 Solutions folders
Add Solution folders:
  • Model
  • Services. In this folder, you store service implementations and service interfaces.
  • ViewModels. In this folder, you store view models.
  • Views. In this folder you add your views.
2.5 Connect the Module with Shell
2.5.1 Add reference
In Shell project add areference to the Module project
2.5.2 Change code in Bootstrapper
Change the code in the bootstrapper so the Module get loaded:

ModuleCatalog moduleCatalog = (ModuleCatalog)this.ModuleCatalog;
moduleCatalog.AddModule(typeof(Module.Module));


3. Add View

3.1 Add xaml

3.1.1 View
Before we can add our map we need to add some references to the ArcGIS for WPF:
Add some esri elements to the view so we can see if it get's loaded correctly:

       
           
                   Url="
http://server.arcgisonline.com/ArcGIS/rest/services/ESRI_StreetMap_World_2D/MapServer"/>
           
       
   



When running the application the end result looks like this:


Sunday, September 18, 2011

Windows 8 and VS2011 developer previews.

Have been busy this weekend checking out the keynotes and some sessions from the Microsoft Build conference last week. Microsoft has released a windows 8 developer preview and a Visual Studio 2011, .Net4.5 developer preview. So I've installed both products. VS11 is included in the 64bit Win8 developer preview, but only the win 8 only features are available and if you install the vs2011 on win7 you can't use the win8 features, So I installed Win8 on Virtualbox see some notes on virtual environment and VS2011 on my win7 machine. I've have made some initial testing:
First Windows 8, the new metro style start page feels like it's spot on when using touch-screens. There is also a mouse and keyboard integration, I don't have touch-screen on my laptop, so I have only used the mouse and keyboard approach, it does not feel perfect though, specially in the metro style applications. In VS2011 you can build metro style applications using C++, C#/VB.Net and HTML/Javascript using the Windows Runtime API. The applications created can be suspended to save battery. A lot of the focus is to save battery time, The fact that Win8 will run on ARM devices, the web sockets support that will be built-in in IE10, IIS8, Windows Runtime Client SDK, .Net4.5...

VS2011 and .Net4.5, .Net4.5 is an in-place update of .Net4.0, that mean that there can be compatibility problems, so any applications built in 4.0 should be tested carefully and as early as possible to avoid problems. .Net4.5 has been made faster. VS2011, the productivity Tools has been integrated into VS2011 also there has been a lot of work done so tools can be used without the need to switch context from the editor. Expression Blend now includes support for HTML and CSS making it easy to use the same Product for all GUI stuff.

Wednesday, August 31, 2011

The breakpoint will not currently be hit. no executable code is associated with this line... VS2008

Was trying to debug a ASMX web service in VS2008. But the breakpoint was not hit and when hovering over the breakpoint it said:
The breakpoint will not currently be hit. no executable code is associated with this line...
did some googling on the topic and guess what: Toggle to release and back to debug again does the trick! Writing it down in case I stumble into this again.

Saturday, July 02, 2011

WP7 + Funbeat API + Reactive Extensions Rx

Started building a sample Windows phone 7 app that are going to consume the Funbeat APIs and show tracks using a ArcGIS for WP7.

Hit some problems with the WP7 project, added a service reference and copied the code from my WPF project, the code did not work. Note to myself: allways start with the smallest subset of an API. The reson the code did not work is that Silverlight and WP7 only support asynchronous calls to a web service.

Well to make life easier Microsoft has shipped WP7 with Reactive Extentions (Rx), (API documentation) that provide support for handling asynchronous calls using observable collections and LINQ-style query operators. Take a look at the HOL for more information on how to use the Rx. So we can add a subscription to the completed event and react when the data gets recived. This is a great thing because the GUI will become more responsive.

Wednesday, June 29, 2011

Setting file security in IIS 7.

Had some problems when migrating a web service to run on Windows 2008 R2 and IIS 7.5. Two of the asmx interfaces needed to have their own file security settings. I could not figure it out but googled it a bit and found the answer in StackOverflow:
1.In IIS7, browse to the directory containing your public.asmx and private.asmx files.
2.The title at the top will reflect the current directory, like "WebService Home". Click the "Content View" button at the bottom.
3.Right-click on your public.asmx file and choose "Switch to Features View".
4.The title should be "public.asmx Home" to confirm that you're managing the one file.
5.Add your IP restrictions. In this case, I think you want an Allow entry for 127.0.0.1 and choose "Edit Feature Settings" from the Action menu to Deny access to unspecified clients.
6.Click your containing folder again (e.g. WebService) and switch to Content View again to repeat these steps on private.asmx.

Very strange UX!?!

Wednesday, June 22, 2011

ESRI ArcGIS for Silverlight, WPF and Windows phone7 version 2.2 released

ESRI released a new version of the ArcGIS for Silverlight, WPF and WP7. Just installed the new version, one great thing is that the GraphicsLayer now has a new property GraphicsSource that makes it possible to databind the graphics into the layer. Should make some of my MVVM stuff easier to implement.

For more info see the blog post: Version 2.2 of the ArcGIS API for Silverlight, WPF, and Windows Phone is now available

Saturday, May 28, 2011

Testing ArcGIS for WPF + Funbeat + Prism.

Trying to make an Wpf Application using ArcGIS for WPF running against Funbeat API to view tracks that I made. Building the application on Microsoft Prism, made a MapModule and a PersonModule and added to two regions in the app.



A Custom Graphics Layer was made that accesses the tracks through the Funbeat APIs. The project uses MVVM Views and ViewModels to separate the GUI from the model. The Xaml files are only using databinding to show the data.

Saturday, May 14, 2011

Using NuGet to package ArcGIS WPF references.

Tested to use NuGet to create a package of the ArcGIS WPF APIs. Installed NuGet Package manager using extension manager in VS2010.



Installed the NuGet Package Explorer and created a package called ArcGIS.Client.WPF and added content, lib, framework and DLLs in the correct framework. Saved the package to a *.nupkg fil in a local folder C:\NUGet\Packages



To get make the package available to NuGet I added the folder in VS2010, Tools | Library Package Manager | Package Manager Settings





Now it's possible to use the package from a project, after starting a WpfProject in VS2010 I start up the consol by choosing, Tools | Library Package Manager | Library Package Console



when the console window opened up it's possible to choose the local folder that we added to the settings




Now it's time to install the package in the project, this is easy, only need to write install-package ArcGIS.Client.WPF and the package gets installed:



References to the package gets added to the project:



If we take look in explorer where the package ended up the filsystem looks like this:



So what's does all this mean, well you can create you own packages that can be easily be added in your projects. This makes it easier to handle dependencies and upgrades. There is a lot of packages on the NuGet Gallery but if you are missing a package or have internal DLL NuGet makes it easy to handle all external dependencies in your projects.

Friday, May 13, 2011

Ranting a bit on the changes in ArcGIS Server 10.1.

ESRI is changing the way the ArcGIS Server works in ArcGIS 10.1, See Considerations for ArcGIS Server developers: A look toward 10.1

We build a lot of SOA webservices leveraging the ArcGIS Server. These are mostly built using the pattern shown here: How to create a geocode and search Web service one of the reasons for building our web services using this pattern, was that the support for Server Object Extensions were poor and still is in ArcGIS 10. You needed to create COM enabled classes that has to be registered on the server etc, no tools, you need to write own tool (Or download SOExplorer) see: SOE Web services


To make the transition easier, I think that ESRI need to give us better tools to handle the SOE, SOAP and REST in ArcGIS Server and in ArcGIS Desktop/Engine. Also provide a solid pattern on how to build enterprise systems where the GIS systems can communicate with other business systems.

Sunday, April 03, 2011

RockPaperAzure Challenge.

Was trying to get the Bot Lab in RockPaperAzure Challenge running in Azure, But got:
Server Error
500 - Internal server error.
There is a problem with the resource you are looking for, and it cannot be displayed.


It worked ok locally but when I published the project to Azure it wouldn't run. Figured it out after a lot of trial and error, I finally found that in the Service Definition *.csdef the following lines are commented out:



  <!--<Sites> 

       <Site name="Web"> 

         <Bindings> 

           <Binding name="Endpoint1" endpointName="Endpoint1" /> 

         </Bindings> 

       </Site> 

     </Sites>-->

 




When I uncomment the lines, the project starts working in Azure. To bad that the Challenge is US only it would have been intresting to se how my bots stacks up to the competition.

Sunday, March 27, 2011

QR code generation for geo-location

Have been playing around with http://zxing.appspot.com/generator/ to generate QR code. No problem to scan in and recreate the coordinate in the phone.

Saturday, February 19, 2011

Solved: The incoming message has an unexpected message format 'Raw'.

As I mentioned in my earlier post the ArcGIS Server REST API returned "plain/text" causing the WCF client to give error message: "The incoming message has an unexpected message format 'Raw'. The expected message formats for the operation are 'Xml'; 'Json'. This can be because a WebContentTypeMapper has not been configured on the binding. See the documentation of WebContentTypeMapper for more details." Found a forum post that helped solve the problem:
JSON and WebInvoke The problem can be solved using a WebContentTypeMapper created a class:

 public  class  JsonContentTypeMapper  :WebContentTypeMapper 

     {

         public  override  WebContentFormat 

                    GetMessageFormatForContentType(string  contentType)

         {

             if  (contentType == "text/plain; charset=utf-8" )

             {

                 return  WebContentFormat .Json;

             }

             else 

             {

                 return  WebContentFormat .Default;

             }

         }

     }

 




And change the app.config:

 <?xml version= "1.0 " encoding= "utf-8 " ?> 

 <configuration> 

   <system.serviceModel> 

     <client> 

       <!--<endpoint address="http://server.arcgisonline.com/ArcGIS/rest/services/Demographics/USA_Median_Household_Income/MapServer/4/query" 

                 binding="webHttpBinding" 

                 bindingConfiguration="ArcGISBinding" 

                 behaviorConfiguration="ArcGIS" 

                 contract="TestRestWCFClient.IArcGISApi" 

                 name="ArcGISREST" />--> 

       <endpoint address= "http://server.arcgisonline.com/ArcGIS/rest/services/Demographics/USA_Median_Household_Income/MapServer/4/query "

                 binding= "customBinding "

                 bindingConfiguration= "ArcGISBinding2 "

                 behaviorConfiguration= "ArcGIS "

                 contract= "TestRestWCFClient.IArcGISApi "

                 name= "ArcGISREST " /> 

     </client> 

     <bindings> 

       <webHttpBinding> 

         <binding name= "ArcGISBinding " maxReceivedMessageSize= "10000000 "/> 

       </webHttpBinding> 

       <customBinding> 

         <binding name= "ArcGISBinding2 "> 

           <webMessageEncoding webContentTypeMapperType= "TestRestWCFClient.JsonContentTypeMapper, TestRestWCFClient, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null " /> 

             <httpTransport manualAddressing= "true " maxReceivedMessageSize= "10000000 " /> 

           </binding> 

       </customBinding> 

     </bindings> 

     <behaviors> 

       <endpointBehaviors> 

         <behavior name= "ArcGIS "> 

           <webHttp/> 

         </behavior> 

       </endpointBehaviors> 

     </behaviors> 

   </system.serviceModel> 

   </configuration>

 

Consume ArcGIS Server REST API using WCF.

Have been trying this all day (It does not work), so I write my findings down so it can be continued another day. Found a great blog post here How to consume REST services with WCF that I tried to adapt create a client proxy against ArcGIS Server REST API. The first part creating a Operation contract an adding an endpoint to was easy to do:

 [ServiceContract ]

     public  interface  IArcGISApi 

     {

         //http://help.arcgis.com/en/arcgisserver/10.0/apis/rest/index.html 

         //http://sampleserver1.arcgisonline.com/ArcGIS/rest/services/Specialty/ESRI_StateCityHighway_USA/MapServer/1/query?geometry=-125.4,35.2,-118.7,43.8&geometryType=esriGeometryEnvelope  

         [OperationContract ]

         [WebGet (

             BodyStyle = WebMessageBodyStyle .Bare,

             ResponseFormat = WebMessageFormat .Json,

             UriTemplate = "?f=json&Where={query}&returnGeometry=true&returnIdsOnly=false&outFields=*" )]

             //UriTemplate = "?method=flickr.interestingness.getList&api_key={apiKey}&extras={extras}")] 

             QueryResponse  Query(string  query);

     }

 



The app.config is configured like this:


 <?xml version= "1.0 " encoding= "utf-8 " ?> 

 <configuration> 

   <system.serviceModel> 

     <client> 

       <endpoint address= "http://server.arcgisonline.com/ArcGIS/rest/services/Demographics/USA_Median_Household_Income/MapServer/4/query "

                 binding= "webHttpBinding "

                 bindingConfiguration= "ArcGISBinding "

                 behaviorConfiguration= "ArcGIS "

                 contract= "TestRestWCFClient.IArcGISApi "

                 name= "ArcGISREST " /> 

     </client> 

 

 

     <bindings> 

       <webHttpBinding> 

         <binding name= "ArcGISBinding " maxReceivedMessageSize= "10000000 "/> 

       </webHttpBinding> 

     </bindings> 

 

 

 

     <behaviors> 

       <endpointBehaviors> 

         <behavior name= "ArcGIS "> 

           <webHttp/> 

         </behavior> 

       </endpointBehaviors> 

     </behaviors> 

   </system.serviceModel> 

   </configuration>

 


And the code for running sending a query looks like this:

 ChannelFactory <IArcGISApi > factory = new  ChannelFactory <IArcGISApi >("ArcGISREST" );

             var  proxy = factory.CreateChannel();

             var  response = proxy.Query(" );

             ((IDisposable )proxy).Dispose();

 


What's not working? Well seems like the response is "text/plain" (checked with fiddler) instead of "application/json". I haven't found a way to force it to be sent as "application/json". The error I get is: "The incoming message has an unexpected message format 'Raw'. The expected message formats for the operation are 'Xml'; 'Json'. This can be because a WebContentTypeMapper has not been configured on the binding. See the documentation of WebContentTypeMapper for more details."


Update: To make it work read: http://mathiaswestin.blogspot.com/2011/02/solved-incoming-message-has-unexpected.html

Saturday, February 12, 2011

Zoom in to feature in ArcGIS Engine using ArcGIS Server and IFind

The second blog post on how to use ArcGIS Server from ArcGIS Engine. This post show how to zoom in on a feature using a IFind searching for a specific value on an attribute.

Basic steps include getting the layer from the map and casting the layer to the IFind interface and searching the layer for the feature. The project are expecting that the layer href="http://server.arcgisonline.com/ArcGIS/rest/services/Demographics/USA_Median_Household_Income/MapServer is loaded in the map.

 Private Sub FindUsingIFindToolStripMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles FindUsingIFindToolStripMenuItem.Click
OnFind()
End Sub

Private Sub OnFind()
Dim state As String = "Alaska"
Dim attribute As String = "Name"
Dim layername As String = "States"
Dim control As AxMapControl = axMapControl1
Dim layer As ILayer = getLayer(layername)
Dim stateGeometry As IGeometry = Me.Find(layer, attribute, state, control.ActiveView)
control.ActiveView.Extent = stateGeometry.Envelope
control.ActiveView.PartialRefresh(esriViewDrawPhase.esriViewAll, Nothing, Nothing)
End Sub



The code for getting the layer from the map.

 Private Function getLayer(ByVal name As String) As ILayer
Dim retLayer As ILayer = Nothing
Dim control As AxMapControl = axMapControl1
For i As Integer = 0 To control.Map.LayerCount - 1
Dim layer As ILayer = control.Map.Layer(i)
retLayer = Me.getLayer(name, layer)
If Not retLayer Is Nothing Then
Exit For
End If
Next
Return retLayer
End Function

Private Function getLayer(ByVal name As String, ByVal layer As ILayer) As ILayer
Dim retLayer As ILayer = Nothing
If TypeOf layer Is ICompositeLayer Then
Dim gLayer As ICompositeLayer = CType(layer, ICompositeLayer)
For i As Integer = 0 To gLayer.Count - 1
Dim l As ILayer = gLayer.Layer(i)
'söker rekursivt efter lagret
retLayer = Me.getLayer(name, l)
If Not retLayer Is Nothing Then
Exit For
End If
Next
Else
If layer.Name.Equals(name) Then
retLayer = layer
End If
End If
Return retLayer
End Function



The code that does the actual IFind. We cast the layer to IFind and use the Find method on the interface. Important to note is that it only work when you search for a value on an attribute, you can't do a custom query on serveral attributes.
 Private Function Find(ByVal layer As ILayer, ByVal field As String, ByVal value As String, ByVal activeView As IActiveView) As IGeometry5
Dim findLayer As IFind = CType(layer, IFind)
Dim fields As String() = {field}
'Söker med IFind efter features med attributet satt till value.
Dim array As IArray = findLayer.Find(value, True, fields, activeView.ScreenDisplay.CancelTracker)
Dim polygon As IPolygon5 = Nothing
For i As Integer = 0 To array.Count - 1
Dim featureFindData As IFeatureFindData2 = CType(array.Element(i), IFeatureFindData2)
Dim featureFields As IFields = featureFindData.Feature.Fields
Dim feature As IFeature = featureFindData.Feature
If (polygon Is Nothing) Then
polygon = CType(feature.Shape, IPolygon5)
Else
Dim topOp As ITopologicalOperator6 = CType(feature.Shape, ITopologicalOperator6)
polygon = CType(topOp.UnionEx(CType(polygon, IGeometry), True), IPolygon5)
End If
Next
Return CType(polygon, IGeometry5)
End Function



The same result as I got in the previous blog post, load the layer showing whole US:



And after running the find tool it shows Alaska: