Monday, August 31, 2009

Free GeoCoding ?

Backup pt http://www.viawindowslive.com/Articles/VirtualEarth/Freereversegeocoding.aspx

This article describes how a website VoyageMap.com utilises a free reverse geocoding
data dump from Geonames.org

I restricted the locations to worldwide cities with greater than 1000 residents. This file was available from http://www.geonames.org/ as a data dump. But you can use their free webservice as well by providing Lat and Long values to http://ws.geonames.org/findNearbyPlaceName?lat=47.3&lng=9



Free reverse geocoding by supplying Lat and Long values.
After downloading Cities data dump and importing into my local database I set up a stored procedure to bring back locations that meet the radius parameter and passed in Lat Long values in following sql


SELECT TOP 3
Country.name as country, City.geonameid,City.name, City.latitude, City.longitude,
Avg(3958.75 * ACos(Sin(@Latitude/57.2958) *
Sin(City.Latitude/57.2958) +
Cos(@Latitude/57.2958) *
Cos(City.Latitude/57.2958) *
Cos(City.Longitude/57.2958 - @Longitude/57.2958))) AS miles
FROM
dbo.GeoNamesCity City
join dbo.GeoNamesCountry Country on City.[country code] = Country.[iso alpha2]
WHERE City.Longitude IS NOT NULL AND City.Longitude <> 0
AND City.Latitude IS NOT NULL AND City.Latitude <> 0
AND @Miles >=
(
3958.75 * ACos(Sin(@Latitude/57.2958) *
Sin(City.Latitude/57.2958) +
Cos(@Latitude/57.2958) *
Cos(City.Latitude/57.2958) *
Cos(City.Longitude/57.2958 - @Longitude/57.2958))
)
GROUP BY Country.name, City.geonameid,City.name, City.latitude, City.longitude
ORDER BY miles
Website users can retrieve upto 3 nearest cities to add travel review by right clicking on map

I used the following code to register the click event


map.AttachEvent("onclick",PopupMenu);
Following is how the event is then handled to popup a menu for users to click on to add review, you can see that left click removes the menu


function PopupMenu(e)
{
if (e.eventName == "onclick")
{
if (e.leftMouseButton)
{
RemovePopupMenu(e);
}
else if (e.rightMouseButton)
{
var menu = document.getElementById('popupmenu');
menu.style.left = e.mapX + 'px' ;
menu.style.top = e.mapY + 'px' ;
menu.style.display='block';
popupmenupoint = DoPixelToLL(e.clientX,e.clientY);
}
}
}


To remove the menu


document.getElementById('popupmenu').style.display='none'
I used a web service to query the database and bring back list of cities (you can also use geonames webservice rather than setup your own), the popupmenupoint variable in javascript holds the LatLong values to run against the geonames data dump.



The site heavily uses AJAX model to give users a seamless experience

Conclusion:
For private websites on a limited budget using MapPoint API is an expensive part of retrieving locations by passing Lat Long values, however with free data sources and web services available you can easily integrate reverse lookup into your website.

I would like to thank geonames.org and viavirtualearth.com to allow me to use their data and code snippets that helped in producing this website.

Article contributed by Mo Majad (VoyageMap.com). Have you got something to contribute?

Saturday, June 13, 2009

JX4201BH & JX4201BH 2 Digit LED Display Datasheet tips

10 pins double digits. The pins are counted from left to right down up counter clockwise facing the part 8.8.
Digits are shown by providing current between 5,6 and [1-4,7-10]

Wednesday, February 25, 2009

Windows Mobile Emulator network

Microsoft Pocket PC Emulator and Network

If you have to develop a software with Microsoft Visual Studio 2005 for a mobile device (for example Pocket PC 2003) which has to access to your network (local area or internet) you must enable the support for the network into the emulator. These are the steps:

1. Download and install the Virtual Machine Network Driver for Microsoft Device Emulator at this address.
I suggest to do the setup with Visual Studio 2005 and the emulator turned off.
2. From the Network Settings select the Local Area Connection, right click and select Properties, check the box near Virtual Machine Network Services
3. In Visual Studio open Tools -> Options
4. Open the Device Tools -> Devices node
5. Select Pocket PC 2003 Emulator and click Properties
6. From the Transport section select the TCP Connect Transport
7. Click the Configure button and select Obtain an IP address automatically using ActiveSync, then close the dialog box
8. Click Emulator Options..., tab Network, check the box Enable NE2000 PCMIA network adapter and bind to: and from the drop down list select your network card
9. Close all the dialog boxes, run your application, in the emulator open then File -> Configure dialog box
10. Check the box or verify the state of the Enable NE2000 PCMIA network adapter and bind to: box, it must be checked

Now from your software you can use the code to connect to internet, databases servers and so on.

Tuesday, February 3, 2009

Alone in the dark - mutex use for single instance of application

Drawback is a denial of service approach

static class Program
{
[STAThread]
static void Main()
{
bool onlyInstance = false;
string mutexName = AssemblyGuid;
// if you want your app to be limited to a single instance across ALL SESSIONS (multiple users & terminal services), then use the following line instead:
// string mutexName = String.Format("Global\\{0}", AssemblyGuid);
Mutex mutex = new Mutex(true, mutexName, out onlyInstance);
if (!onlyInstance) {
IntPtr hwndFirstInstance = WinApi.FindWindow(null, applicationName); // For FindWindow to work, applicationName must be the same as the title (the Text property) of your MainForm.
WinApi.PostMessage(
hwndFirstInstance,
WinApi.WM_SHOWFIRSTINSTANCE,
IntPtr.Zero,
IntPtr.Zero);
return;
}
Application.Run(new MainForm);
GC.KeepAlive(mutex);
}
const string applicationName = "YourApplicationNameGoesHere";
static public string ApplicationName
{
get { return applicationName; } // You could use an Assembly Attribute Accessor instead of a variable, but it involves a bit more code.
}
static public string AssemblyGuid
{
get
{
object[] attributes = Assembly.GetExecutingAssembly().GetCustomAttributes(typeof(System.Runtime.InteropServices.GuidAttribute), false);
if (attributes.Length == 0) {
return String.Empty;
}
return ((System.Runtime.InteropServices.GuidAttribute)attributes[0]).Value;
}
}
}

public class WinApi
{
public static readonly int WM_SHOWFIRSTINSTANCE = RegisterWindowMessage("WM_SHOWFIRSTINSTANCE");

[DllImport("user32")]
public static extern bool PostMessage(IntPtr hwnd, int msg, IntPtr wparam, IntPtr lparam);

[DllImport("user32")]
public static extern int RegisterWindowMessage(string message);

[DllImport("user32.dll")]
public static extern bool ShowWindow(IntPtr hWnd, int nCmdShow);

[DllImport("user32.dll")]
public static extern bool SetForegroundWindow(IntPtr hWnd);

[DllImport("user32.dll")]
public static extern IntPtr FindWindow (string lpClassName, string lpWindowName);

public static void ShowToFront(string windowName)
{
IntPtr window = FindWindow(null, windowName);
ShowWindow(window, 1);
SetForegroundWindow(window);
}
}

public partial class MainForm : System.Windows.Forms.Form
{
bool minimizedToTray;

public MainForm()
{
InitializeComponent();
this.Text = Program.ApplicationName;
}
private void btnMinToTray_Click(object sender, EventArgs e)
{
MinimizeToTray();
}
void MinimizeToTray()
{
notifyIcon = new NotifyIcon();
notifyIcon.Click += new EventHandler(NotifyIconClick);
notifyIcon.Icon = this.Icon;
notifyIcon.Text = Program.ApplicationName;
notifyIcon.Visible = true;
this.ShowInTaskbar = false;
this.Hide();
minimizedToTray = true;
}
public void ShowWindow()
{
if (minimizedToTray) {
notifyIcon.Visible = false;
this.ShowInTaskbar = true;
this.Show();
minimizedToTray = false;
} else {
WinApi.ShowToFront(this.Text);
}
}
void NotifyIconOpen(Object sender, System.EventArgs e)
{
ShowWindow();
}
protected override void WndProc(ref Message message)
{
if (message.Msg == WinApi.WM_SHOWFIRSTINSTANCE) {
ShowWindow();
}
base.WndProc(ref message);
}
}

Thursday, January 29, 2009

SQL Server triggers used to prevent users to modify data

IF EXISTS (SELECT * FROM sys.triggers WHERE object_id = OBJECT_ID(N'[InterzicereModificari]'))
DROP TRIGGER [InterzicereModificari]
GO


CREATE TRIGGER dbo.DenyWrite_ViramenteAntet
ON [dbo].[Viramente - antet]
AFTER INSERT,DELETE,UPDATE
AS
BEGIN
RAISERROR ('Nu mai aveti dreptul de a modifica din acest program', 16, 1);
END
GO

Friday, January 16, 2009

MemoryDictionaryCache reminder


public interface ICache
{
void Reset();
void Load();
string LoadMessage { get; set; }
}

public class MemoryDictionaryCache<T, Z> : ICache
{
public MemoryDictionaryCache(Func<Dictionary<T, Z>> loadCache, string loadMessage, Func<Dictionary<T,Z>, T, Z> retrieveValue)
{
_load = loadCache;
LoadMessage = loadMessage;
_retrieveValue = retrieveValue;
}

private Func<Dictionary<T, Z>> _load;
Func<Dictionary<T, Z>, T, Z> _retrieveValue;
public string LoadMessage { get; set; }

private Dictionary<T, Z> _cache = null;
private Dictionary<T, Z> Cache
{
get
{
if (_cache == null)
Load();
return _cache;
}
}

public void Reset()
{
_cache = null;
}

public void Load()
{
using (var waitWindow = new WaitWindow(LoadMessage ?? "Asteptati incarcarea datelor"))
{
_cache = _load();
}
}

public Z GetValue(T forKey)
{
return _retrieveValue(Cache, forKey);
}
}

private Dictionary<Type, ICache> _caches = new Dictionary<Type, ICache>();

private void Initialize()
{
_caches.Add(typeof(ContractID), new MemoryDictionaryCache<ContractID, ContractEntity>(
()=>new Dictionary<ContractID, ContractEntity>(),
"Incarc contractele",
(dic, contractID)=>dic.GetValue(contractID)));
}

public ContractEntity GetContractul(ContractID contractID)
{
return ((MemoryDictionaryCache<ContractID, ContractEntity>)_caches[typeof(ContractID)]).GetValue(contractID);
}