Calculate walking times across route - networkx

I am trying to calculate travel distances across a walkable street network I've downloaded using OSMNX. I have generated a route from an origin to a destination using NetworkX's nx.shortest_path function. However, whenever I calculate my route setting "travel_time" as weight, I get inaccurate results. I was wondering if this might have to do with the "speed_kph" attribute in the network. Is there a way to manually set speeds to equate walking speeds (e.g. 5 kph?)?

You are using the nx.shortest_path_length function and the travel_time attribute. Note the travel_time attribute is not present by default in your graph. In order to add it you need to use ox.add_edge_travel_times.
The Networkx function shortest_path_length states in it's documentation:
weight -
If None, every edge has weight/distance/cost 1. If a string, use this edge attribute as the edge weight. Any edge attribute not present defaults to 1.
Since the travel_time is not present you get the shortest path which has the minimum edges.
This can be verified by trying:
weight = nx.shortest_path_length(walk_network, origin_nn, destination_nn, weight = 'fake_key')
Since usually in walking you assume a constant speed, a possible solution would be to use the edge length and calculate the speed separately.
For example:
import osmnx as ox
import networkx as nx
WALKING_SPEED = 1.4 # m/s average walkihg speed
walk_network = ox.graph.graph_from_address('Piccadilly Circus, London', dist = 1000, network_type = 'walk')
origin = (-0.13492669985021463, 51.51016491413415)
destination = (-0.12516, 51.51112)
origin_nn = ox.distance.nearest_nodes(walk_network, origin[0], origin[1])
destination_nn = ox.distance.nearest_nodes(walk_network, destination[0], destination[1])
length = nx.shortest_path_length(walk_network, origin_nn, destination_nn, weight = 'length')
duration = length / WALKING_SPEED / 60
print('The shortest walking route is {:.2f} meters and will take {:.2f} minutes'.format(length, duration))

Related

How to find the local horizon longitude of the highest point of the ecliptic

I would like to use pyephem or skyfield to find the degree of the local horizon (starting from South = 0°) at which is located the highest point of the ecliptic. Note that I am not trying to find the culmination of a planet. It could well be that, when looking South, there is no planet on the ecliptic by that time/latitude, but there will still be a highest point of the ecliptic. Can anyone help?
While it’s likely that someone will soon jump in with a closed-form solution that uses spherical trigonometry — in which case it’s likely that Skyfield or PyEphem will only be used to determine the Earth orientation — here’s a quick way to get an answer within about a degree:
Generate the ecliptic as 360 points one degree apart across the sky.
Compute the altitude and azimuth of each one.
Choose the highest.
The result agrees closely to what I see if I open Stellarium, turn on the ecliptic, and choose a field star right near the point where the ecliptic reaches the highest point in the sky.
import numpy as np
from skyfield import api, framelib
from skyfield.positionlib import Apparent
𝜏 = api.tau
ts = api.load.timescale()
eph = api.load('de421.bsp')
bluffton = api.Topos('40.74 N', '84.11 W')
t = ts.utc(2021, 2, 16, 22, 52)
angle = np.arange(360) / 360.0 * 𝜏
zero = angle * 0.0
f = framelib.ecliptic_frame
d = api.Distance([np.sin(angle), np.cos(angle), zero])
v = api.Velocity([zero, zero, zero])
p = Apparent.from_time_and_frame_vectors(t, f, d, v)
p.center = bluffton
alt, az, distance = p.altaz()
i = np.argmax(alt.degrees) # Which of the 360 points has highest altitude?
print('Altitude of highest point on ecliptic:', alt.degrees[i])
print('Azimuth of highest point on ecliptic:', az.degrees[i])
The result:
Altitude of highest point on ecliptic: 67.5477569215633
Azimuth of highest point on ecliptic: 163.42529398930515
This is probably a computationally expensive enough approach that it won’t interest you once you or someone else does the spherical trigonometry to find an equation for the azimuth; but at the very least this might provide numbers to check possible formulae against.

networkx: diameter gives 13 want to find what are those nodes or distance

I want to find the farthest nodes. I used diameter and it gave me an integer value, what should i do to get those points at the start and end of the diamete?
i.e find the farthest points in a graph by using some function.
The nx.diameter seems like it's only to find the distance of the longest shortest path between nodes and none of the built in functions in the networkx.algorithms.distance_measures (docs) module seem to compute what you're really looking for. To get the furthest nodes, one option is to use a sequence of calls to nx.single_source_shortest_path_length(G,n) where G is the graph and n is the source node. This returns the length of the shortest paths from n to all nodes in G as a dict keyed by the nodes and the values are the distance from the node to the source node n. Then you can look through these dicts to find which pair(s) of nodes have the longest length. Something like this should work.
def get_furthest_nodes(G):
sp_length = {} # dict containing shortest path distances for each pair of nodes
diameter = None # will contain the graphs diameter (length of longest shortest path)
furthest_node_list = [] # will contain list of tuple of nodes with shortest path equal to diameter
for node in G.nodes:
# Get the shortest path from node to all other nodes
sp_length[node] = nx.single_source_shortest_path_length(G,node)
longest_path = max(sp_length[node].values()) # get length of furthest node from node
# Update diameter when necessary (on first iteration and when we find a longer one)
if diameter == None:
diameter = longest_path # set the first diameter
# update the list of tuples of furthest nodes if we have a best diameter
if longest_path >= diameter:
diameter = longest_path
# a list of tuples containing
# the current node and the nodes furthest from it
node_longest_paths = [(node,other_node)
for other_node in sp_length[node].keys()
if sp_length[node][other_node] == longest_path]
if longest_path > diameter:
# This is better than the previous diameter
# so replace the list of tuples of diameter nodes with this nodes
# tuple of furthest nodes
furthest_node_list = node_longest_paths
else: # this is equal to the current diameter
# add this nodes tuple of furthest nodes to the current list
furthest_node_list = furthest_node_list + node_longest_paths
# return the diameter,
# all pairs of nodes with shortest path length equal to the diameter
# the dict of all-node shortest paths
return({'diameter':diameter,
'furthest_node_list':furthest_node_list,
'node_shortest_path_dicts':sp_length})
Note, this solution assumes that the graph is connected (strongly connected for directed graphs), which yours should be since you got a solution for the diameter using nx.diameter. This should have similar runtime as the call to the diamater because that function does similar steps, it just doesn't keep all the path links and nodes that result in the diameter. Note the furthest_node_list item in the return dict will have each pair of nodes twice just in the opposite direction (if nodes a and b have shortest path equal to the diameter, both (a,b) and (b,a) will be in the list).
The nodes on the periphery are those nodes separated by a distance of diameter. Easy to calculate these in networkx. For some connected graph g:
n1, n2 = nx.periphery(g)
diameter_nodes = nx.shortest_path(g, source = n1, target = n2)
note that this assumes you will have exactly two nodes on the periphery. In general, this is not the case and you will have to implement some logic to determine which shortest path you want to calculate. Also, not all pairs of nodes in the periphery necessarily have a distance equal to the diameter. so this is something else to be cautious of.

Gravity in accelerometric measurements

I have taken from a data set the values ​​of x and z of activity (e.g. walking, running) detected by an accelerometer. Since the data collected also contains the gravity values, I removed it with the following filter in Matlab:
fc = 0.3;
fs = 50;
x = ...;
y = ...;
z = ...;
[but,att] = butter(6,fc/(fs/2));
gx = filter(but,att,x);
gy = filter(but,att,y);
gz = filter(but,att,z);
new_x = x-gx;
new_y = y-gy;
new_z = z-gz;
A = magnitude(new_x,new_y,new_z);
plot(A)
Then I calculated the magnitude value and plotted the magnitude value on a graph.
However, every graph, even after removing gravity, starts with a magnitude of 1g (9.8 m / s ^ 2), why? Should not it start at 0 since I removed gravity?
You need to wait for the filter value to ramp up. Include some additional data that you don't graph at the beginning of the file for this purpose.
How accurate do your calculations need to be? With walking and running the angle of the accelerometer can change, so the orientation of the gravity vector can change throughout the gait cycle. How much of a change in orientation you can expect to see depends on the sensor location and the particular motion you are trying to capture.

How to get coords between 2 points

I cannot find exactly what I'm looking for or reading google documentation I missed it, I just need a function or whatever to submit 2 point, start and end, and get X waypoint in between.
Is there some api like "www.somesite.com/api.php?start=43.12,12.23&end=44.12,12.23&number_of_waypoints=5" that return some json?
thank you!
First of all, this will require working with geodesics, which are the shortest lines passing through two points around the Earth, assuming the Earth is an ellipsoid. WGS84 is the standard coordinate system you will see most widely used for "latitude + longitude" coordinates, and this assumes the Earth is an ellipsoid.
To solve this problem, you first need to find the azimuth (bearing angle from north) and distance between two coordinates. The way to calculate this is by solving the inverse geodesic problem.
Once we have this distance (let's say in metres), we can divide it by n, where n - 1 is the number of waypoints we want in between the line. This gives us the distance d metres between each waypoint.
Now, we need to plot points at intervals of d metres along this line. To do this, we can solve the direct geodesic problem. This gives us a new set of coordinates after moving a given distance from a given point with a given azimuth. We can do this repeatedly to get new points moving d metres from the previous point each time. One thing to note with this is that the resultant azimuth to the end of the line from different points within the line will vary, so the destination azimuth must be obtained after each stage and used for calculating the next point.
Solving the direct and inverse geodesic problems requires mathematical formulas, of which multiple are available. However, for your PHP application, you are probably best not trying to implement these yourself, but instead use a library which can do this for you. One popular library for PHP which does this is called phpgeo.
Here's an example of how this might be implemented with phpgeo:
<?php
use Location\Coordinate;
use Location\Distance\Vincenty;
use Location\Bearing\BearingEllipsoidal;
$numPoints = 5;
$coordsA = new Coordinate(50.0, 0.0);
$coordsB = new Coordinate(51.0, 1.0);
$bearingCalculator = new BearingEllipsoidal();
$distanceCalculator = new Vincenty();
// Inverse geodesic problem
// Calculate total length of line between coords
$totalDistance = $distanceCalculator->getDistance($coordsA, $coordsB);
$intervalDistance = $totalDistance / ($numPoints + 1);
// Inverse geodesic problem
// Calculate angle to destination
$currentBearing = $bearingCalculator->calculateBearing($coordsA, $coordsB);
$currentCoords = $coordsA;
$points = [];
for ($i = 0; $i < $numPoints; $i++) {
// Direct geodesic problem
// Calculate new point along line
$currentCoords =
$bearingCalculator->calculateDestination($currentCoords,
$currentBearing,
$intervalDistance);
// Add these new coordinates to the list
array_push($points, $currentCoords);
// Inverse geodesic problem
// Recalculate angle to destination
$currentBearing =
$bearingCalculator->calculateBearing($currentCoords,
$coordsB);
}
// Print out the list of points
foreach ($points as $point) {
echo "{$point->getLat()}, {$point->getLng()}\n";
}

How to find maximum pixel intensity of the two regions obtained after finding the threshold of the image

We are working on DIP project where we found out the threshold of the gray scale image. Now we have to * find the maximum intensity of the two regions that we got, one region whose pixels are less than the threshold and the other whose pixels are greater than it. *
PS. We are not converting the image into binary image after finding the threshold. We just have to separate pixels in two regions and find the maximum intensity in each region
PS: We are working on MATLAB
Actually it is pretty simple to do.
Here is a function to do so:
function [ lowThrMaxIntns, highThrMaxIntns ] = FindMaxIntnesity ( mInputImage, thrLevel )
% Pixels which are lower than the threshold level
mLowThrImage = zeros(size(mInputImage));
% Pixels which are higher than the threshold level
mHightThrImage = zeros(size(mInputImage));
mLowThrImage(mInputImage < thrLevel) = mInputImage(mInputImage < thrLevel);
mHightThrImage(mInputImage >= thrLevel) = mInputImage(mInputImage >= thrLevel);
[lowThrMaxIntns lowThrMaxIntnsIdx] = max(mLowThrImage(:));
[highThrMaxIntns highThrMaxIntnsIdx] = max(mHightThrImage(:));
end
The output are only the intensities of the pixels.
If you need the pixel location, use the Idx variables (Use ind2sub for the sub scripts form).