Wednesday, April 29, 2015

Using Open Layers to display Map

Here is a simple example on how to load a map using "Open Layers" open source GIS API.

==== JavaScript Code ========

$(document).ready(function () {

LoadMap();

}); 


function LoadMap() {

var map = new ol.Map({

target: 'map',

layers: [


new ol.layer.Tile({

source: new ol.source.MapQuest({ layer: 'sat' })

})

],


view: new ol.View({

center: ol.proj.transform([37.41, 8.82], 'EPSG:4326', 'EPSG:3857'),

zoom: 4

})

});

}

=================================================

======== Code from Index.html =============================

<link rel="stylesheet" href="http://openlayers.org/en/v3.2.1/css/ol.css" type="text/css">

<script src="http://openlayers.org/en/v3.2.1/build/ol.js" type="text/javascript"></script>

<script src="scripts/mainJavaScript.js"></script>

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

============================================================

These lines should display a "World Map".

Happy Coding.

Cheers
Adam




 

Saturday, March 28, 2015

Convert Scientific Notation String to Double in c#


I was working with conversion of some scientific notation numbers like this "2.09550901805872E-05" which was represented in string to double.
 
When I did that using regular ToConvert function , it was throwing an exception.
 
After few research, I found out that it should be done using Parse function and NumberStyles as shown below.
 
Double.Parse("<Scientific Exponent String>", NumberStyles.AllowExponent | NumberStyles.AllowDecimalPoint);
 
Hope this tip helps.
 
Cheers
Adam

Friday, February 27, 2015

Calling MVC Server Side Function without using JQuery



I have a Web Method, which is part of my MVC controller.

       [HttpPost]        public JsonResult AddProduct(string productName, string productPrice)
        {
            JsonResult togoValue = new JsonResult();
            try
            {
                Product newProduct = new Product(productName, Convert.ToDouble(productPrice));
                if (newProduct.IsDuplicate() == false)
                {
                    newProduct.Save();
                }
                else
                {
                    throw new Exception("Product with same name and price already exists!");
                }
                togoValue = Json(InMemoryDB.GetAllRecordsinJSONFormat());
            }
            catch (Exception ex)
            {
                togoValue = Json("Error : " + ex.Message.ToString());
            }
            return togoValue;
        }


Examine the highlighted items above.  

HttpPost - This keyword mentions this method can be called only by a POST call.
JsonResult - This is the return type of the web method.
productName and productPrice - These are the input arguments of two different types.

I am calling this server side function using the following JavaScript call without using JQuery.

       function SendProducttoServer(inProdName, inProdPrice) {
            var newProduct = "productName=" + inProdName + "&productPrice=" + inProdPrice ;            var xmlhttp = new XMLHttpRequest();
            if (xmlhttp == null) {
                alert("Browser does not support XMLHttpRequest.");
            }
            else {
                xmlhttp.onreadystatechange = function () {
                    if (xmlhttp.readyState == 4 && xmlhttp.status == 200) {
                        if (xmlhttp.responseText.indexOf("Error") > -1)
                        {
                            ShowUserMessage(xmlhttp.responseText);
                        }
                        else
                        {
                            ShowUserMessage("Added new record !");
                            var allRecords = JSON.parse(xmlhttp.responseText);
                            UpdateTable(allRecords);
                        }
                    }
                }
                xmlhttp.open("POST", "/Default/AddProduct", true);
                xmlhttp.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
                xmlhttp.send(newProduct);

            }
        }


Note the highlighted items in the above JavaScript function. This function performs a POST call and submits the arguments to the Server Side Function.

This type of calling will come in handy if the client insists not to use JQuery or other third party scripts.

Happy Coding !

Cheers
Adam

Sunday, January 25, 2015

Using POST when connecting to remote ASP.NET API Web Service


ASP.NET API Web Service web method calls can be modified to receive POST input. The reason is , sometimes we may need to pass sensitive information like password or other information. There are many ways to do this. Here is a new technique which I used.

=============


        [HttpPost] (This attribute is required to tell the WebMethod is a POST.)
        [ActionName("login")]
        public ManagerOutput getUserInfo(HttpRequestMessage inmessage) (The whole request is being used as input.)
        {
            ManagerOutput output = new ManagerOutput(); (This is the output the methos will send.)
            output.operation = "login";
            try
            {
                var theRequestBody = "";
                try
                {
                    theRequestBody = System.Text.Encoding.UTF8.GetString(Convert.FromBase64String(theRequestBody)); (The whole request can be passed in encoded 64 bit. Here it is being decoded. So the information sent is not visible easily.)
                    theRequestBody = inmessage.Content.ReadAsStringAsync().Result; (This is where the message content (body) is extracted from the request string.)
                }
                catch(Exception ex)
                {
                    throw new Exception("Error in ReadAsStringAsync." + ex.ToString());
                }
                if (theRequestBody == null)
                   throw new Exception("theRequestBody is null");
                ModelUserPin objModelUserPin = new ModelUserPin();
                try
                {
                    objModelUserPin = new System.Web.Script.Serialization.JavaScriptSerializer().Deserialize<ModelUserPin>(theRequestBody); (This is where JavaScript JSON content is converted to CSharp class. Here the class name is ModelUserPin.)
                }
                catch (Exception ex)
                {
                    throw new Exception("Error in JavaScriptSerializer." + ex.ToString());
                }
 
                // Add more business logic here.

                //return Newtonsoft.Json.JsonConvert.SerializeObject(output); (If required the CSharp class can be converted to JSON string.)

                return output; (When returning the results , the whole CSharp class is sent out.)
            }
            catch (Exception ex)
            {
                output.status = "ERROR: " + ex.ToString();
                //return Newtonsoft.Json.JsonConvert.SerializeObject(output);
                return output;
            }
        }

 =============
When calling this function from the JavaScript side, this is the code to use.
=======
this.validateUser = function (username, pin) {
    console.log('validateUser');
    var bodyContent  = Base64.encode( JSON.stringify({ "userId": username, "userPin": pin }) ); (This is where the request is encoded.)
    var url = urlBase + loginUserURl;
    $.ajax({
        url: url,
        type: 'POST',
        dataType: 'json',
        timeout: 60000,
        data: bodyContent,
        contentType: 'application/json; charset=utf-8', (This content type is important. Then only the JavaScript will encode the csharp class coming from the Web Service. Else the control will goto error: instead of success:)
        error: function (errData) {
            validateUserFailedCallback(errData);
        },
        success: function (data) {
            validateUserCallback(data);
        }
    });
};

Here is the value for Base64 used in the code above.


// Create Base64 Object

var Base64 = { _keyStr: "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=", encode: function (e) { var t = ""; var n, r, i, s, o, u, a; var f = 0; e = Base64._utf8_encode(e); while (f < e.length) { n = e.charCodeAt(f++); r = e.charCodeAt(f++); i = e.charCodeAt(f++); s = n >> 2; o = (n & 3) << 4 | r >> 4; u = (r & 15) << 2 | i >> 6; a = i & 63; if (isNaN(r)) { u = a = 64 } else if (isNaN(i)) { a = 64 } t = t + this._keyStr.charAt(s) + this._keyStr.charAt(o) + this._keyStr.charAt(u) + this._keyStr.charAt(a) } return t }, decode: function (e) { var t = ""; var n, r, i; var s, o, u, a; var f = 0; e = e.replace(/[^A-Za-z0-9\+\/\=]/g, ""); while (f < e.length) { s = this._keyStr.indexOf(e.charAt(f++)); o = this._keyStr.indexOf(e.charAt(f++)); u = this._keyStr.indexOf(e.charAt(f++)); a = this._keyStr.indexOf(e.charAt(f++)); n = s << 2 | o >> 4; r = (o & 15) << 4 | u >> 2; i = (u & 3) << 6 | a; t = t + String.fromCharCode(n); if (u != 64) { t = t + String.fromCharCode(r) } if (a != 64) { t = t + String.fromCharCode(i) } } t = Base64._utf8_decode(t); return t }, _utf8_encode: function (e) { e = e.replace(/\r\n/g, "\n"); var t = ""; for (var n = 0; n < e.length; n++) { var r = e.charCodeAt(n); if (r < 128) { t += String.fromCharCode(r) } else if (r > 127 && r < 2048) { t += String.fromCharCode(r >> 6 | 192); t += String.fromCharCode(r & 63 | 128) } else { t += String.fromCharCode(r >> 12 | 224); t += String.fromCharCode(r >> 6 & 63 | 128); t += String.fromCharCode(r & 63 | 128) } } return t }, _utf8_decode: function (e) { var t = ""; var n = 0; var r = c1 = c2 = 0; while (n < e.length) { r = e.charCodeAt(n); if (r < 128) { t += String.fromCharCode(r); n++ } else if (r > 191 && r < 224) { c2 = e.charCodeAt(n + 1); t += String.fromCharCode((r & 31) << 6 | c2 & 63); n += 2 } else { c2 = e.charCodeAt(n + 1); c3 = e.charCodeAt(n + 2); t += String.fromCharCode((r & 15) << 12 | (c2 & 63) << 6 | c3 & 63); n += 3 } } return t } }
=======

Also when debugging / testing the code , make sure to POST to http site and not to a https (SSL) site. If you attempt to POST from http to https , it will abort and throw error. It will not even POST.
 
Hope the tips mentioned here, helps you in your project.
Thanks
Adam
 
 
 

Thursday, December 25, 2014

Issues observed in "ESRI GeoEvent Processor"


 
When working with "ESRI GeoEvent Processor", I noted couple of issues.

Issue 1 :

If the "ESRI GeoEvent Processor" service is updating or adding new GIS features based on the "GeoEvent", it will work fine for few hours and then the server performance will be extremely slow and will become unusable at some time. Then we have to either restart the GEP Service and ArcGIS Server Service or restart the server itself.

After some trial and error, I found out that, if the "ArcSDE" data is a "Versioned" data then this issues happens. In the "Unversioned" ArcSDE data this will not occur.

Issue 2:

In the "GeoEvent Processor" web service, if you add an output to add new GIS feature, there is an option to "Delete Old Features". Even if you enable this, it will not delete the old features. The reason is, it performs a query like DATE_TIME < '[Some Date Time Value]'. For some reason this query does not contain the proper SQL Date Time query syntax and hence it fails to delete any features.

The only work around is to periodically delete the old features from the ArcGIS REST endpoint feature service url.

Hope these tips are helpful. If there are any new solutions, please add it in the comments section below.

Happy Holidays

Cheers
Adam

Saturday, November 29, 2014

Calling remote JSON data web service url using

Here  is a sample code to call remote JSON data web service using JQuery Ajax call.

Use this simple javascript function when calling remote JSON data web service.

function callRemoteWebService(){
    var url = "htttp://someremote/web/service/url" ;
    $.ajax({
       
url:url,
        type: 'GET',
        dataType: 'json',
        timeout: 20000,
        error: function(errData){
            handleError(errData);
        },
        success: function(successData){
            handleError(
successData
);
        }
    });
}


Happy Coding !



Monday, October 27, 2014

Access data across domains


When working with jQuery and JavaScript, there was a need to access a "Remote Web Service" which was hosted from a different server.

Since I was debugging using my local laptop, the application was throwing errors like "Cross-domain policy file missing" or "Unable to access data across domains".

After some research, I found that we can make both Internet Explorer and Chrome browser work with data from different domains.

In Internet Explorer do this.

Under Security Tab, click "Custom Level" button. Scroll Down to Miscellaneous Section and choose "Access data sources across domains" - Enable.

In Chrome do this.

Create a simple short-cut on Desktop. Add the following line as the "Start up Application" for the short-cut.

"C:\Program Files (x86)\Google\Chrome\Application\Chrome.exe" --allow-file-access-from-files --disable-web-security

This will open the Chrome Browser in a different mode capable of accessing data across domains.

Hope this tip helps.

Happy Coding !
 

Thursday, September 25, 2014

Working with ESRI GeoEvent Processor


I was asked to setup the “ESRI GeoEvent Processor” for one of our projects. It was quite exciting to work with it. We can simulate real-time data streams. The real-time data streams can trigger events. We can use these events to build additional logic based on our business needs.

First it was not clear where to start and what are the steps to do. After figuring it out, I thought of documenting here so it will give a starting point for anyone who is interested.

These are the main things to focus when working with “ESRI GeoEvent Processor”.
  1. Prepare the GIS data exactly the way you want for your business needs.
  2. Prepare the “Real Time Data” stream. This can be a series of Latitude and Longitude values with other information. For example flight data or truck data. Any data which contains a stream of X and Y values with time stamp that can be mapped on the Map.
  3. In the ESRI GeoEvent Processor, create the right kind of “Inputs” and “Outputs”. There are several choices here. Based on the business requirement the correct one should be chosen. A little bit of planning and few trails and error will produce expected results.
  4. Use the “Inputs” and “Outputs” to create the “GeoEvent Service”. This “GeoEvent Service” will use the “Inputs” and “Outputs” to produce the desired results.

Based on the “GeoEvent”, it is possible to update an existing GIS Feature in a “FeatureService” in ArcGIS Server REST endpoint. It is also possible to add New GIS Features.

Hope you got an idea where to start!

Happy configuring.

Cheers
Adam

 

 

 

Sunday, August 24, 2014

HTTP Web Service using ASP.NET Web API

Creating HTTP WebService using ASP.NET Web API is really simple.
 
After few reading/coding work, I got an idea on what needs to be implemented.
 
1. Make sure the routing table is configured correctly like shown below. The 'WebApiConfig' class will be present in the folder 'App_Start' folder. Note down the 'action' text added in the route.
 
public static class WebApiConfig
    {
        public static void Register(HttpConfiguration config)
        {
            // Web API configuration and services
            // Web API routes
            config.MapHttpAttributeRoutes();
            config.Routes.MapHttpRoute(
                name: "DefaultApi",
                routeTemplate: "api/{controller}/{action}/{id}",
                defaults: new { id = RouteParameter.Optional }
            );
        }
    }
 
 
2. Create the Controller Class. See the sample class 'ManagerController' shown below. This class should be derived from 'ApiController'. Also note down the first portion of the controller class name 'Manager' and the action name 'getSomeInfo'. This will be used later when you invoke the 'HTTP Web Service'.
 
public class ManagerController : ApiController
{
        #region Public Web Methods
        [HttpGet]
        [ActionName("getSomeInfo")]
        public SomeOutputClass SomeGetWebFunction(string someInput)
        {
     // Some code goes here.
     // This should return SomeOutputClass.
  }
}
 
These are the only two steps we need.
 
Compile the application and host it in IIS Server and give some application name. For example 'TestApp'.
 
The HTTP Web Service is ready.
 
Simply call the 'WebService' as shown below and you should get the results as 'JSON' text format.

The HTTP Web Service call will be invoked like shown below.
 
 
There are many details in ASP.NET Web API. The idea I have provided will simply get you started.
 
Read more information for further details.
 
Happy Coding !
 
Cheers
Adam

 

Monday, July 28, 2014

Connect to remote SQL Server over the Internet


I installed SQL Server 2008 R2 edition on a Virtual Machine (VM). I was supposed to access this SQL Server from my laptop over the internet.

I created the .udl file on my laptop and tried to access this remote SQL Server in the VM. It was not connecting. Tried many things but still unable to connect to the remote SQL Server on the VM.

(A quick note on the UDL file. Create a simple text document and change the extension to .udl. Double-click the UDL file. This will provide tools to establish a connection to any database based on the drivers available on the laptop. We can establish the connection to a remote server. If you open the .udl file in a notepad you can see the complete connection string. This connection string can be used in any application to communicate with the database.)

After checking few internet pages here is what I found. There are two items to check and fix.

Item 1:

In the SQL Server Configuration Manager, check the “Protocols”. The “TCP/IP” protocol should be enabled and make sure the IP address uses the port 1433. This is the default SQL port.

Item 2:

Check the Windows Firewall Settings. Add an “Inbound Rule” to allow communication through the port 1433.

After fixing these two items, I was able to communicate to my remote SQL Serve from my laptop over the Internet.

Hope this tip helps you.

Sunday, June 22, 2014

Creating Dynamic Radio Button Controls in Silverlight MVVM model

There was a need to create dynamic "Radio Button" controls in one of my projects. This was a Silverlight MVVM project.

Since the "View" is isolated from "ViewModel" and connected only through binding, it was not clear on how to do this task.

After few research I found the answer.

This is the code that needs to go on the XAML side. Note the "ItemsControl" element. The itemssource will take in a List of RadioButtonClass.

<Grid DataContext="{StaticResource ViewModel}">
        <StackPanel>
            <ItemsControl ItemsSource="{Binding RadioButtonClassList}">
                <ItemsControl.ItemTemplate>
                    <DataTemplate>
                        <RadioButton GroupName="OneGroup" IsChecked="{Binding IsSelected}" Content="{Binding RadioButtonName}"></RadioButton>
                    </DataTemplate>
                </ItemsControl.ItemTemplate>
            </ItemsControl>
        </StackPanel>
 </Grid>


Note the binding properties (IsSelected and RadioButtonName) in the "RadioButton" control.

The "RadioButtonClass" can be defined something like this.

public class RadioButtonClass : INotifyPropertyChanged
{
   public string RadioButtonName;
   public bool IsSelected;
}

In the "ViewModel" class if you add a property which is a List like this List<RadioButtonClass> and bind it to the View as shown in the above XAML snippet (<Grid DataContext="{StaticResource ViewModel}">) then the RadioButtons will show up. The number or radio buttons is equal to the number of items in the List.

Hope this tip helps.

Happy Coding !


 

All Blogs so far ...