/// <summary> /// Retrieve geocode address using Google Api /// </summary> /// <param name="pluginExecutionContext">Execution context</param> /// <param name="organizationService">Organization service</param> /// <param name="tracingService">Tracing service</param> /// <param name="notificationService">Notification service</param> public void ExecuteGeocodeAddress(IPluginExecutionContext pluginExecutionContext, IOrganizationService organizationService, ITracingService tracingService) { //Contains 5 fields (string) for individual parts of an address ParameterCollection InputParameters = pluginExecutionContext.InputParameters; // Contains 2 fields (double) for resultant geolocation ParameterCollection OutputParameters = pluginExecutionContext.OutputParameters; //Contains 1 field (int) for status of previous and this plugin ParameterCollection SharedVariables = pluginExecutionContext.SharedVariables; tracingService.Trace("ExecuteGeocodeAddress started. InputParameters = {0}, OutputParameters = {1}", InputParameters.Count().ToString(), OutputParameters.Count().ToString()); try { // If a plugin earlier in the pipeline has already geocoded successfully, quit if ((double)OutputParameters[LatitudeKey] != 0d || (double)OutputParameters[LongitudeKey] != 0d) { return; } // Get user Lcid if request did not include it int Lcid = (int)InputParameters[LcidKey]; string _address = string.Empty; if (Lcid == 0) { var userSettingsQuery = new QueryExpression("usersettings"); userSettingsQuery.ColumnSet.AddColumns("uilanguageid", "systemuserid"); userSettingsQuery.Criteria.AddCondition("systemuserid", ConditionOperator.Equal, pluginExecutionContext.InitiatingUserId); var userSettings = organizationService.RetrieveMultiple(userSettingsQuery); if (userSettings.Entities.Count > 0) { Lcid = (int)userSettings.Entities[0]["uilanguageid"]; } } // Arrange the address components in a single comma-separated string, according to LCID _address = GisUtility.FormatInternationalAddress(Lcid, (string)InputParameters[Address1Key], (string)InputParameters[PostalCodeKey], (string)InputParameters[CityKey], (string)InputParameters[StateKey], (string)InputParameters[CountryKey]); // Make Geocoding call to Google API WebClient client = new WebClient(); var url = $"https://{GoogleConstants.GoogleApiServer}{GoogleConstants.GoogleGeocodePath}/json?address={_address}&key={GoogleConstants.GoogleApiKey}"; tracingService.Trace($"Calling {url}\n"); string response = client.DownloadString(url); // Post ... tracingService.Trace("Parsing response ...\n"); DataContractJsonSerializer jsonSerializer = new DataContractJsonSerializer(typeof(GeocodeResponse)); // Deserialize response json object objResponse = jsonSerializer.ReadObject(new MemoryStream(Encoding.UTF8.GetBytes(response))); // Get response as an object GeocodeResponse geocodeResponse = objResponse as GeocodeResponse; // Unbox into our data contracted class for response tracingService.Trace("Response Status = " + geocodeResponse.Status + "\n"); if (geocodeResponse.Status != "OK") { throw new ApplicationException($"Server {GoogleConstants.GoogleApiServer} application error (Status {geocodeResponse.Status})."); } tracingService.Trace("Checking geocodeResponse.Result...\n"); if (geocodeResponse.Results != null) { if (geocodeResponse.Results.Count() == 1) { tracingService.Trace("Checking geocodeResponse.Result.Geometry.Location...\n"); if (geocodeResponse.Results.First()?.Geometry?.Location != null) { tracingService.Trace("Setting Latitude, Longitude in OutputParameters...\n"); // update output parameters OutputParameters[LatitudeKey] = geocodeResponse.Results.First().Geometry.Location.Lat; OutputParameters[LongitudeKey] = geocodeResponse.Results.First().Geometry.Location.Lng; } else { throw new ApplicationException($"Server {GoogleConstants.GoogleApiServer} application error (missing Results[0].Geometry.Location)"); } } else { throw new ApplicationException($"Server {GoogleConstants.GoogleApiServer} application error (more than 1 result returned)"); } } else { throw new ApplicationException($"Server {GoogleConstants.GoogleApiServer} application error (missing Results)"); } } catch (Exception ex) { // Signal to subsequent plugins in this message pipeline that geocoding failed here. OutputParameters[LatitudeKey] = 0d; OutputParameters[LongitudeKey] = 0d; //TODO: You may need to decide which caught exceptions will rethrow and which ones will simply signal geocoding did not complete. throw new InvalidPluginExecutionException(string.Format("Geocoding failed at {0} with exception -- {1}: {2}" , GoogleConstants.GoogleApiServer, ex.GetType().ToString(), ex.Message), ex); } }
public void ExecuteGeocodeAddress(IPluginExecutionContext pluginExecutionContext, IOrganizationService organizationService, ITracingService tracingService = null) { ParameterCollection InputParameters = pluginExecutionContext.InputParameters; // 5 fields (string) for individual parts of an address ParameterCollection OutputParameters = pluginExecutionContext.OutputParameters; // 2 fields (double) for resultant geolocation tracingService.Trace("ExecuteGeocodeAddress started. InputParameters = {0}, OutputParameters = {1}", InputParameters.Count().ToString(), OutputParameters.Count().ToString()); try { // If a plugin earlier in the pipeline has already geocoded successfully, quit if ((double)OutputParameters[LatitudeKey] != 0d || (double)OutputParameters[LongitudeKey] != 0d) { return; } int Lcid = (int)InputParameters[LcidKey]; string _address = string.Empty; if (Lcid == 0) { var userSettingsQuery = new QueryExpression("usersettings"); userSettingsQuery.ColumnSet.AddColumns("uilanguageid", "systemuserid"); userSettingsQuery.Criteria.AddCondition("systemuserid", ConditionOperator.Equal, pluginExecutionContext.InitiatingUserId); var userSettings = organizationService.RetrieveMultiple(userSettingsQuery); if (userSettings.Entities.Count > 0) { Lcid = (int)userSettings.Entities[0]["uilanguageid"]; } } _address = GisUtility.FormatInternationalAddress(Lcid, (string)InputParameters[Address1Key], (string)InputParameters[PostalCodeKey], (string)InputParameters[CityKey], (string)InputParameters[StateKey], (string)InputParameters[CountryKey]); var street = ((string)InputParameters[Address1Key]).Replace(" ", "+"); var city = ((string)InputParameters[CityKey]).Replace(" ", "+"); var state = (string)InputParameters[StateKey]; var postcode = (string)InputParameters[PostalCodeKey]; tracingService.Trace("street " + street); tracingService.Trace("postcode " + postcode); tracingService.Trace("city " + city); tracingService.Trace("state " + state); var url = $"https://{trimbleMaps.ApiServer}{trimbleMaps.GeocodePath}?street={street}&city={city}&state={state}&postcode={postcode}®ion=NA&dataset=Current"; tracingService.Trace($"Calling {url}\n"); Uri requestUri = new Uri(url); HttpWebRequest req = WebRequest.Create(requestUri) as HttpWebRequest; req.Headers["Authorization"] = "03F68EA06887B2428771784EFEB79DDD"; req.ContentType = "application/json"; try { using (HttpWebResponse response = (HttpWebResponse)req.GetResponse()) { //string txtResponse = ""; //using (StreamReader sr = new StreamReader(response.GetResponseStream())) //{ // string txtResponse.Text = sr.ReadToEnd(); //} tracingService.Trace("Parsing response ...\n"); tracingService.Trace(response.ToString() + '\n'); string txtResponse = ""; using (StreamReader sr = new StreamReader(response.GetResponseStream())) { txtResponse = sr.ReadToEnd(); } txtResponse = txtResponse.Remove(0, 1); txtResponse = txtResponse.Remove(txtResponse.Length - 1, 1); tracingService.Trace(txtResponse + '\n'); tracingService.Trace("about to serial\n"); DataContractJsonSerializer jsonSerializer = new DataContractJsonSerializer(typeof(TrimbleMapsGeocodeResponse)); tracingService.Trace("about to read object\n"); object objResponse = jsonSerializer.ReadObject(new MemoryStream(Encoding.UTF8.GetBytes(txtResponse))); tracingService.Trace("about to ilist\n"); var geocodeResponseNotList = objResponse as TrimbleMapsGeocodeResponse; tracingService.Trace("Checking geocodeResponse.Result...\n"); tracingService.Trace(geocodeResponseNotList.ToString() + "not list\n"); tracingService.Trace("hope i got it all geez\n"); //if (geocodeResponse.First() != null) //{ //if (geocodeResponse.Count() == 1) //{ tracingService.Trace("Checking geocodeResponse.Coords...\n"); if (geocodeResponseNotList?.Coords != null) { tracingService.Trace("Setting Latitude, Longitude in OutputParameters...\n"); OutputParameters[LatitudeKey] = Convert.ToDouble(geocodeResponseNotList.Coords.Lat); OutputParameters[LongitudeKey] = Convert.ToDouble(geocodeResponseNotList.Coords.Lon); } else { throw new ApplicationException($"Server {trimbleMaps.ApiServer} application error (missing Coords)"); } //} // else throw new ApplicationException($"Server {trimbleMaps.ApiServer} application error (more than 1 result returned)"); //} //else throw new ApplicationException($"Server {trimbleMaps.ApiServer} application error (missing response body)"); } } catch (Exception ex) { throw new InvalidPluginExecutionException(string.Format("Response parse failed at {0} with exception -- {1}: {2}" , trimbleMaps.ApiServer, ex.GetType().ToString(), ex.Message), ex); } } catch (Exception ex) { // Signal to subsequent plugins in this message pipeline that geocoding failed here. OutputParameters[LatitudeKey] = 0d; OutputParameters[LongitudeKey] = 0d; //TODO: You may need to decide which caught exceptions will rethrow and which ones will simply signal geocoding did not complete. throw new InvalidPluginExecutionException(string.Format("Geocoding failed at {0} with exception -- {1}: {2}" , trimbleMaps.ApiServer, ex.GetType().ToString(), ex.Message), ex); } }