The following is code being used in an app I am working on. The app will try to detect an Estimote beacon and then output in Android notifications the distance of the beacon. The issue I am running into is that the notification is being sent every second, when it should be sent every 1/10th of a second - from setting the foreground scan period. Changing the advertising interval of the beacon didn't seem to have much of an effect either. Is there something I am missing with this?
beaconManager.setBackgroundScanPeriod(100,0);
beaconManager.setForegroundScanPeriod(100,0);
beaconManager.setRangingListener(new BeaconManager.RangingListener() {
int count = 0;
#Override
public void onBeaconsDiscovered(Region region, List<Beacon> beacons) {
if (beacons.size() < 1) {
return;
}
count++;
String distance = "" + getDistance(beacons.get(0).getRssi(), beacons.get(0).getMeasuredPower());
String beaconName = beacons.get(0).getName();
showNotification(count + " Name + Distance", beaconName + ": " + distance);
}
});
I'm writing a POC for WinPhone 8 (I have a Nokia 928 running the 8.1 release).
One of the features I'm working with is GeoLocator and I'm noticing some odd behavior. My app gets your current location and then tracks your movement and calculates the distance between the two points. The odd behavior is that I'm sitting still and the PositionChanged event is firing! What gives? I've yet to move and my app already says the distance from the origin and my current location is ~9Meters.
Is this normal behavior for GPS? If so, what is the recommended method of dealing with it?
Here is how my GeoLocator is setup:
_Geolocator = new Geolocator();
_Geolocator.DesiredAccuracy = PositionAccuracy.High;
_Geolocator.MovementThreshold = 5;
_Geolocator.ReportInterval = 1000;
I have a button that gets the current location and starts the position changed event (chopping code for brevity):
Geoposition position = await _Geolocator.GetGeopositionAsync();
_trackLocation = true;
_currentLocation = position;
OrigLongitude = _currentLocation.Coordinate.Longitude;
OrigLatitude = _currentLocation.Coordinate.Latitude;
_Geolocator.PositionChanged += _Geolocator_PositionChanged;
Message = "tracking location";
and the PositionChanged event:
_currentLocation = args.Position;
//calculate the distance
double d = _pointTracker.DistanceTo(_currentLocation.Coordinate.Latitude, _currentLocation.Coordinate.Longitude);
double accuracy = _currentLocation.Coordinate.Accuracy;
if (true == show.Contains("tracking X"))
{
show = "tracking Y " + accuracy.ToString();
}
else
{
show = "tracking X " + accuracy.ToString();
}
DispatcherHelper.CheckBeginInvokeOnUI(() => { Distance = d; });
DispatcherHelper.CheckBeginInvokeOnUI(() => { Message = show; });
DispatcherHelper.CheckBeginInvokeOnUI(() => { Longitude = _currentLocation.Coordinate.Longitude; });
DispatcherHelper.CheckBeginInvokeOnUI(() => { Latitude = _currentLocation.Coordinate.Latitude; });
The show junk just lets me see that a message showing that the event is firing. the only thing of interest in it is the GPS accuracy I'm getting back (usually it's about 3 meters, in doors it is 9 meters).
Any direction or help would be greatly appreciated.
TIA
A map I created last year using Google Maps API V3 and Fusion Tables V1 has stopped functioning properly in the last week or so. I am not sure if I missed an update that has deprecated my code or if there's another explanation. In brief, the following code queries my fusion table and if a match is found it returns data for an info window. However, it is now returning false every time. The addInfoWindow() function is firing fine. The issue appears to be either in the query itself or the data that's returned. Additionally, the pin is dropping in the correct location on the map so the coordinates are not the issue.
This issue can be replicated by entering an address in the field. For demonstration purposes, 9132 Kingston Pike 37923 should return true. Clicking inside any polygon will return the intended results.
Thank you for any guidance you can provide.
// query
var script = document.createElement('script');
var url = ['https://www.googleapis.com/fusiontables/v1/query?'];
url.push('sql=');
var query = "SELECT * FROM " +
tableid + " WHERE ST_INTERSECTS(geometry, CIRCLE(LATLNG(" + coordinate.lat() + "," + coordinate.lng() + "), 0.001))";
var encodedQuery = encodeURIComponent(query);
url.push(encodedQuery);
url.push('&callback=addInfoWindow');
url.push('&key=' + apiKey);
script.src = url.join('');
var head = document.getElementsByTagName('head')[0];
head.appendChild(script);
// call back function
function addInfoWindow(data) {
infowindow.close();
initialize();
var rows = data['rows'];
if (rows)
{
console.log("inside if statement");
for (var i = 0; i < 1; i++)
{
console.log("inside for loop: " + rows[i][0]);
infowindow.setContent("<div style='width:250px;'><h2>"+ rows[i][1] + "</h2><p>The neighborhood contact in your area would love to hear from you! </p><p>Click <a href='https://cspctystn.infellowship.com/GroupSearch/ShowGroup/" + rows[i][0] + "' target='_blank'>here</a> to get their information.</p><p> </p><p>If you desire to communicate with Community Life staff, contact -- removed --.<p><br/><br/></div>");
//console.log(rows[i][1] + ": " + rows[i][0]);
infowindow.setPosition(coordinate);
map.setCenter(coordinate);
map.setZoom(15);
infowindow.open(map);
}
}
else
{
console.log("error");
infowindow.setContent("<div style='width:250px;'><h2>Oops!</h1><p> It seems we don't have a neighborhood contact in your area.</p><p>Please communicate with our <a href='http://www.cspc.net/communitylife' target= '_blank' >Community Life</a> staff for more information. -- removed --<p></div>");
infowindow.setPosition(coordinate);
map.setCenter(coordinate);
map.setZoom(15);
infowindow.open(map);
}
}
How to implement the following:
User defines an address
User defines a color
Service searches for a corresponding building on the google map
Service fills the found building on the map with the color
I know how to:
1.find lat/long of the address
2.draw the polygon
So, to do the task I need to get polygon coordinates of building from address. How to?
(1) Acquire image tile
(2) Segment buildings based on pixel color (here, 0xF2EEE6).
(3) Image cleanup (e.g. erosion then dilation) + algorithm to acquire pixel coordinates of polygon corners.
(4) Mercator projection to acquire lat/long of pixel
You can convert the address to geographic coordinates by the use of the Google Geocoding API.
https://maps.googleapis.com/maps/api/geocode/json?address=SOME_ADDRESS&key=YOUR_API_KEY
Then, you can use Python and a styled static map to obtain the polygon of the building (in pixel coordinates) at some location:
import numpy as np
from requests.utils import quote
from skimage.measure import find_contours, points_in_poly, approximate_polygon
from skimage import io
from skimage import color
from threading import Thread
center_latitude = None ##put latitude here
center_longitude = None ##put longitude here
mapZoom = str(20)
midX = 300
midY = 300
# Styled google maps url showing only the buildings
safeURL_Style = quote('feature:landscape.man_made|element:geometry.stroke|visibility:on|color:0xffffff|weight:1')
urlBuildings = "http://maps.googleapis.com/maps/api/staticmap?center=" + str_Center + "&zoom=" + mapZoom + "&format=png32&sensor=false&size=" + str_Size + "&maptype=roadmap&style=visibility:off&style=" + safeURL_Style
mainBuilding = None
imgBuildings = io.imread(urlBuildings)
gray_imgBuildings = color.rgb2gray(imgBuildings)
# will create inverted binary image
binary_imageBuildings = np.where(gray_imgBuildings > np.mean(gray_imgBuildings), 0.0, 1.0)
contoursBuildings = find_contours(binary_imageBuildings, 0.1)
for n, contourBuilding in enumerate(contoursBuildings):
if (contourBuilding[0, 1] == contourBuilding[-1, 1]) and (contourBuilding[0, 0] == contourBuilding[-1, 0]):
# check if it is inside any other polygon, so this will remove any additional elements
isInside = False
skipPoly = False
for othersPolygon in contoursBuildings:
isInside = points_in_poly(contourBuilding, othersPolygon)
if all(isInside):
skipPoly = True
break
if skipPoly == False:
center_inside = points_in_poly(np.array([[midX, midY]]), contourBuilding)
if center_inside:
# approximate will generalize the polygon
mainBuilding = approximate_polygon(contourBuilding, tolerance=2)
print(mainBuilding)
Now, you can convert the pixel coordinates to latitude and longitude by the use of little JavaScript, and the Google Maps API:
function point2LatLng(point, map) {
var topRight = map.getProjection().fromLatLngToPoint(map.getBounds().getNorthEast());
var bottomLeft = map.getProjection().fromLatLngToPoint(map.getBounds().getSouthWest());
var scale = Math.pow(2, map.getZoom());
var worldPoint = new google.maps.Point(point.x / scale + bottomLeft.x, point.y / scale + topRight.y);
return map.getProjection().fromPointToLatLng(worldPoint);
}
var convertedPointsMain = [];
for (var i = 0; i < pxlMainPolygons[p].length; i++) {
var conv_point = {
x: Math.round(pxlMainPolygons[p][i][1]),
y: Math.round(pxlMainPolygons[p][i][0])
};
convertedPointsMain[i] = point2LatLng(conv_point, map);
}
console.log(convertedPointsMain);
Might I humbly suggest you use OpenStreetMaps for this instead ?
It's a lot easier, because then you can use the OverPass API.
However, polygons might not match with google-maps or with state survey.
The latter also holds true if you would use google-maps.
// https://wiki.openstreetmap.org/wiki/Overpass_API/Overpass_QL
private static string GetOqlBuildingQuery(int distance, decimal latitude, decimal longitude)
{
System.Globalization.NumberFormatInfo nfi = new System.Globalization.NumberFormatInfo()
{
NumberGroupSeparator = "",
NumberDecimalSeparator = ".",
CurrencyGroupSeparator = "",
CurrencyDecimalSeparator = ".",
CurrencySymbol = ""
};
// [out: json];
// way(around:25, 47.360867, 8.534703)["building"];
// out ids geom meta;
string oqlQuery = #"[out:json];
way(around:" + distance.ToString(nfi) + ", "
+ latitude.ToString(nfi) + ", " + longitude.ToString(nfi)
+ #")[""building""];
out ids geom;"; // ohne meta - ist minimal
return oqlQuery;
}
public static System.Collections.Generic.List<Wgs84Point> GetWgs84PolygonPoints(int distance, decimal latitude, decimal longitude)
{
string[] overpass_services = new string[] {
"http://overpass.osm.ch/api/interpreter",
"http://overpass.openstreetmap.fr/api/interpreter",
"http://overpass-api.de/api/interpreter",
"http://overpass.osm.rambler.ru/cgi/interpreter",
// "https://overpass.osm.vi-di.fr/api/interpreter", // offline...
};
// string url = "http://overpass.osm.ch/api/interpreter";
// string url = "http://overpass-api.de/api/interpreter";
string url = overpass_services[s_rnd.Next(0, overpass_services.Length)];
System.Collections.Specialized.NameValueCollection reqparm = new System.Collections.Specialized.NameValueCollection();
reqparm.Add("data", GetOqlBuildingQuery(distance, latitude, longitude));
string resp = PostRequest(url, reqparm);
// System.IO.File.WriteAllText(#"D:\username\Documents\visual studio 2017\Projects\TestPlotly\TestSpatial\testResponse.json", resp, System.Text.Encoding.UTF8);
// System.Console.WriteLine(resp);
// string resp = System.IO.File.ReadAllText(#"D:\username\Documents\visual studio 2017\Projects\TestPlotly\TestSpatial\testResponse.json", System.Text.Encoding.UTF8);
System.Collections.Generic.List<Wgs84Point> ls = null;
Overpass.Building.BuildingInfo ro = Overpass.Building.BuildingInfo.FromJson(resp);
if (ro != null && ro.Elements != null && ro.Elements.Count > 0 && ro.Elements[0].Geometry != null)
{
ls = new System.Collections.Generic.List<Wgs84Point>();
for (int i = 0; i < ro.Elements[0].Geometry.Count; ++i)
{
ls.Add(new Wgs84Point(ro.Elements[0].Geometry[i].Latitude, ro.Elements[0].Geometry[i].Longitude, i));
} // Next i
} // End if (ro != null && ro.Elements != null && ro.Elements.Count > 0 && ro.Elements[0].Geometry != null)
return ls;
} // End Function GetWgs84Points
I've been working on this for hours, the closest I have come is finding a request uri that returns a result with a polygon in it. I believe it specifies the building(boundary) by editids parameter. We just need a way to get the current editids from a building(boundary).
The URI I have is:
https://www.google.com/mapmaker?hl=en&gw=40&output=jsonp&ll=38.934911%2C-92.329359&spn=0.016288%2C0.056477&z=14&mpnum=0&vpid=1354239392511&editids=nAlkfrzSpBMuVg-hSJ&xauth=YOUR_XAUTH_HERE&geowiki_client=mapmaker&hl=en
Part of the result has what is needed:
"polygon":[{"gnew":{"loop":[{"vertex":[{"lat_e7":389364691,"lng_e7":-923341133},{"lat_e7":389362067,"lng_e7":-923342783},{"lat_e7":389361075,"lng_e7":-923343356},{"lat_e7":389360594,"lng_e7":-923342477},
I was intrigued on this problem and wrote a solution to it. See my github project.
The Google Maps API contains a GeocoderResults object that might be what you need. Specifically the data returned in the geometry field.
I am displaying the different marker on the map , the problem is that sometimes (specially when I reset the web server) the map is loaded properly and it even shows the shadow of the points but the markers are not shown/visible on the map.However on the subsequent calls the markers are shown properly (perhaps cached , but not sure). This behavior is consistent in all browsers namely IE 6/7/8 , Chrome , Firfox 3.5.6.
The javascript shown below creates the marker. On the sideline, as markers can be of different sizes, I need to first determine there width and size (other wise they look deformed).
var imgTemp = new Image();
imgTemp.name = "img_" + i.toString();
imgTemp.src = groupMarkerUrl; //url to the actual image
point = new GLatLng(parseFloat(latitude), parseFloat(longitude));
var icon = new GIcon(G_DEFAULT_ICON);
icon.image = groupMarkerUrl;
icon.iconSize = new GSize(imgTemp.width, imgTemp.height); //Width x Height
icon.iconAnchor = new GPoint(14, 15);
icon.infoWindowAnchor = new GPoint(5, 1);
marker = new GMarker(point, icon);
map.setCenter(point, 13);
//build the information box
var htmlContent = "<div style=\"color:#000000\"><span style=\"font-weight:bold;\">" + title + "</span><br/>";
if (address != "") {
htmlContent += address + " ";
}
if (zipcode != "") {
htmlContent += "<br/>" + zipcode + ", ";
}
if (city != "") {
htmlContent += city;
}
if (telephone != "") {
htmlContent += "<br/>Tel : " + telephone;
}
if (fax != "") {
htmlContent += "<br/>Fax : " + fax;
}
htmlContent += "</div>";
map.addOverlay(marker);
markerKeys.push(stamp);
markers[stamp] = marker;
//Add legends with group markers one for each group
if (null == legends[groupId]) {
legends[groupId] = groupMarkerUrl;
var nbsp = document.createTextNode(" ");
var image = document.createElement("img");
image.setAttribute("src", groupMarkerUrl);
image.setAttribute("style", "margin-left:10px !important; border:\"0\";");
pushpinPnlConsole.appendChild(nbsp);
pushpinPnlConsole.appendChild(image);
pushpinPnlConsole.setAttribute("style", "display:block");
}
eval("GEvent.addListener(markers[stamp] , \"click\", function(){markers['" + stamp + "'].openInfoWindowHtml(windowHtmls['" + stamp + "']);});");
windowHtmls[stamp] = htmlContent;
opticianTBody.appendChild(row);
Thanks.
Your problem is that
imgTemp.src = groupMarkerUrl; //url to the actual image
takes some time to complete. Since you use imgTemp.width and imgTemp.height without waiting for the image to load, those values are likely to be zero. The API will plot your icons at zero size.
In browsers other than MSIE, you can omit the icon.iconSize (and not copy the details from G_DEFAULT_ICON as mentioned by mopoke) and the marker will default to the image size if the image has arrived by the time the marker gets displayed. In MSIE, for PNG images, the API uses the AplphaImageLoader which defaults to size zero if a size is not specified.
The workround is to preload your images properly, by placing this code inline, so that it gets executed before the onload event
var imgTemp = new Image();
imgTemp.name = "img_" + i.toString();
imgTemp.src = groupMarkerUrl; //url to the actual image
And placing your icon creation code in an onload function, so that it doesn't get executed until after all the images loaded by the inline code have been completely fetched.
Not sure why you're using G_DEFAULT_ICON in your constructor.
To do a custom icon, use something like:
var icon = new GIcon();
icon.image = groupMarkerUrl;
//...
After you reset the server and you try and load the image referenced in groupMarkerUrl, do you see it correctly?