GeoDjango + PostGIS calculates wrong Distances - python

I just installed PostGIS with GeoDjango. Everything worked fine, but now I have a problem and cant find out the reason for this.
I have model like this:
from django.contrib.gis.db import models
class Shop(models.Model):
name = models.CharField(max_length=80)
point = models.PointField(null=True, blank=True)
objects = models.GeoManager()
And I set its point to this position (49.794254,9.927489). Then i create a point like this:
pnt = fromstr('POINT(50.084068 8.238381)')
The distance between this points should be about ~ 125 km, but when i do this:
results = Shop.objects.distance(pnt)
print results[0].distance.km
I'm getting always about 60 km too much in my result, so it returns 190 km! My SRIDs of both points are 4326... probably something wrong with that?
And maybe another interesting fact, when i do this:
pnt.distance(shop.point)
it returns 1.713790... as a result.
What am I doing wrong? Any alternatives for me to use with python + django? If there is a better solution I would not need to use PostGIS.
Hope you can help me!
Chris

I just ran this query in postgis :
select round(CAST(ST_Distance_Sphere(ST_GeomFromText('POINT(49.794254 9.927489)',4326), ST_GeomFromText('POINT(50.084068 8.238381)',4326)) As numeric)/1000.0,2) as distance_km;
distance_km
-------------
190.50
the result is in fact 190.50, so it seems there's nothing wrong with your 190 km result
same result with this awesome page, there is a brief explanation of how to calculate this distances.
the 1.713790... result seems to be in the same units of the srid, or in other words that number is not in meters.
EDIT
Ooohh I just saw your problem you misplaced the lat and lon, in the WKT format, Longitude comes first so the real query should be:
select round(CAST(ST_Distance_Sphere(ST_GeomFromText('POINT(9.927489 49.794254)',4326), ST_GeomFromText('POINT(8.238381 50.084068)',4326)) As numeric)/1000.0,2) as distance_km;
distance_km
-------------
125.10
so the points should be created like this
POINT(9.927489 49.794254)
POINT(8.238381 50.084068)

Related

Why I can't get the shadow price from Gurobipy while the model is feasible?

I'm trying to solve peer to peer market optimization problem. Since the price of each trade between different participants can be different, I want to draw the price of each trade. And the problem should be a continuous model, because the trade amount can be at any level.
The model already works fine without problem, I can get the trade amount of each trade using like model.variables.trade[t,k,y].x.
But the problem is when I try to get the shadow price from the related constraints, it shows : GurobiError: Unable to retrieve attribute 'Pi'.
I can't find out how comes this error since the model is already feasible, and what I do is get an attribute which already exists.
The related part of my code shows as follows:
def _build_constraints(self):
m = self.model
P_nm3 = self.variables.P_nm3
agents = self.data.agents
timewindow = self.data.timewindow
windowinterval = self.data.windowinterval
budget = self.data.budget
P_n = self.variables.P_n
self.constraints.pnmmatch = {}
......
for t in self.data.interval:
for i in range(len(P_nm3[t])):
for j in range(len(P_nm3[t][0])):
self.constraints.pnmmatch[t,i,j] = m.addConstr(
P_nm3[t][i][j],
gb.GRB.EQUAL,
-P_nm3[t][j][i]
)
.......
poolmarket = marketclear()
poolmarket.optimize()
print(poolmarket.constraints.pnmmatch[0,1,6])
print(type(poolmarket.constraints.pnmmatch))
print(poolmarket.constraints.pnmmatch[0,1,6].pi)
shadow_price = poolmarket.model.getAttr(gb.GRB.Attr.Pi)
The result is:
<gurobi.Constr R1001>
<class 'dict'>
AttributeError: Unable to retrieve attribute 'pi'
both poolmarket.constraints.pnmmatch[0,1,6].pi or poolmarket.model.getAttr(gb.GRB.Attr.Pi) doesn't work.
If I comment on the last two lines about pi, the models works pretty fine.
But in a simpler similar model where the constraint is:
for t in self.data.interval:
for i in range(len(P_nm3[t])):
for j in range(len(P_nm3[t][0])):
self.constraints.pnmmatch[t] = m.addConstr(
P_nm3[t][i][j],
gb.GRB.EQUAL,
-P_nm3[t][j][i]
)
Then I'm able to draw the pi value with poolmarket.constraints.pnmmatch[0].pi command.
How can I solve this?
Thanks in advance!

A python code for converting the longitude of a planet into 360 degree format

It is the usual practice to mention the longitude of the planet
by it's rasi position and the degrees.
Example: Sun in virgo 23 degrees. To convert this into a 360 format you have to add 150 degree the starting point of virgo. Adding the 23 to 150 gives 173 degrees.
I have the dictionary:
RasiDegree={"Aries":0,"Tarus":30,"Gemini":60,"Cancer":90,"Leo":120,
"Virgo":150,"Libra":180,"Scorpio":210,"Sagitarius":240,"Capricorn":270,"Aquarius":300,"Pisces":330}
for rasi,degree in RasiDegree.items():
print(rasi, degree)
the print out comes out correctly.
To access any particular rasi, my code is print(RasiDegree["rasi"])
So far so good. How do I write the python prograame to calculate the above.
I tried to get the user input for the rasi and the degree. I am stuck. Should I write a function?
Any help will be greatly appreciated.
Use below function. This function takes rasi name and degree by user as input and return in 360 fomat.
def calculate():
rasi = input()
degree = input()
if(rasi in RasiDegree.keys()):
return RasiDegree[rasi]+int(degree)

Pyephem elevation seems to be wrong

I'm trying to compute satellite positions using pyephem.
For most cases it seems to provide valid data. But for ~10% space-track's TLEs its results are wrong. For example:
tlelines = [
'0 SCOUT X-4 DEB',
'1 00722U 63053C 18107.73853716 .10519988 29718+0 80827-1 0 9998',
'2 00722 78.3737 228.3264 0048420 261.5483 98.0279 15.81271626581437'
]
sat = ephem.readtle(*tlelines)
now = ephem.now() # 43314.17601851852
sat.compute(now)
print sat.elevation # computed altitude, according to documentation
Result is 9.793773380577526e+18 which is definitely wrong. According to space-track apogee and perigee are 359 and 294 km.
What's wrong and how can I fix this computation?
PS. Python v.2, pyephem v.3.7.6.0
The problem appears to be that your coordinates are too old; satellite coordinates are generally only accurate for a couple of weeks to either side of the moment they're released. In this case:
print(sat._epoch)
the coordinates were 4 months old when you tried them out:
2018/4/17 17:43:30
If you try a value like now = '2018-04-18' I think you'll get a more reasonable number.

Latitude and Longitude to Address

I have about 8000 + Latitudes and Longitudes.
I need to extract(reverse code), them to location, possibly city.
Initially I checked with Google Maps, but according to their terms we should not hit their services with our scripts.
Even the OpenStreetMaps doesnt allow us to hit their servers repeatedly. They have some time limit.
So, I downloaded the latitudes and logitudes for locations. I wrote a python script,
import tabular as tb
import csv
citiesLatLongData = tb.tabarray(SVfile="D:/latitude-longitude/citieslatlong.csv")
allData = tb.tabarray(SVfile="C:/Users/User/Desktop/alldata.csv")
latlonglocs = {'a1':"Car Nicobar",'a2':"Port Blair",'a3':"Hyderabad",'a4':"Kadapa",'a5':"Puttaparthi",
'a6':"Rajahmundry",'a7':"Tirupati",'a8':"Vijayawada",'a9':"Vishakhapatnam",'a10':"Itanagar",
'a11':"Dibrugarh",'a12':"Dispur",'a13':"Guwahati",'a14':"North Lakhimpur",'a15':"Silchar",
'a16':"Gaya",'a17':"Patna",'a18':"Chandigarh",'a19':"Raipur",'a20':"Silvassa",
'a21':"Daman",'a22':"Bawana",'a23':"New Delhi",'a24':"Mormugao",'a25':"Panaji",
'a26':"Ahmedabad",'a27':"Bhavnagar",'a28':"Bhuj",'a29':"Gandhinagar",'a30':"Jamnagar",
'a31':"Kandla",'a32':"Rajkot",'a33':"Vadodara",'a34':"Hisar",'a35':"Bilaspur",
'a36':"Dharamsala",'a37':"Kulu",'a38':"Shimla",'a39':"Jammu",'a40':"Srinagar",'a41':"Jamshedpur",
'a42':"Ranchi",'a43':"Bangalore",'a44':"Belgaum",'a45':"Bellary",'a46':"Hubli Dharwad",
'a47':"Mandya",'a48':"Mangalore",'a49':"Mysore",'a50':"Cochin",'a51':"Kozhikode",
'a52':"Thiruvananthapuram",'a53':"Bingaram Island ",'a54':"Kavaratti",'a55':"Bhopal",'a56':"Gwalior",
'a57':"Indore",'a58':"Jabalpur",'a59':"Khandwa",'a60':"Satna",'a61':"Ahmadnagar",
'a62':"Akola",'a63':"Aurangabad",'a64':"Jalna",'a65':"Kolhapur",'a66':"Mumbai",
'a67':"Nagpur",'a68':"Nasik",'a69':"Pimpri",'a70':"Pune",'a71':"Solapur",
'a72':"Imphal",'a73':"Shillong",'a74':"Aizawl",'a75':"Kohima",'a76':"Bhubaneswar",
'a77':"Jharsuguda",'a78':"Karaikal",'a79':"Mahe",'a80':"Pondicherry",'a81':"Yanam",
'a82':"Amritsar",'a83':"Pathankot",'a84':"Jaipur",'a85':"Jodhpur",'a86':"Kota",
'a87':"Udaipur",'a88':"Gangtok",'a89':"Chennai",'a90':"Coimbatore",'a91':"Madurai",
'a92':"Nagercoil",'a93':"Thiruchendur",'a94':"Thiruvannaamalai",'a95':"Thoothukudi",
'a96':"Tiruchirappalli",'a97':"Tirunelveli",'a98':"Vellore",'a99':"Agartala",
'a100':"Agra",'a101':"Allahabad",'a102':"Bareilly",'a103':"Gorakhpur",'a104':"Jhansi",
'a105':"Kanpur",'a106':"Lucknow",'a107':"Varanasi",'a108':"Dehradun",'a109':"Pantnagar",
'a110':"Kolkata",'a111':"Siliguri"}
latlongs = {'a1':[9.15,92.8167],'a2':[11.6667,92.7167],'a3':[17.45,78.4667],'a4':[14.4833,78.8333],
'a5':[14.1333,77.7833],'a6':[16.9667,81.7667],'a7':[13.65,79.4167],'a8':[16.5333,80.8],
'a9':[17.7,83.3],'a10':[27.0833,93.5667],'a11':[27.4833,95.0167],'a12':[26.0833,91.8333],
'a13':[26.1667,91.5833],'a14':[27.2333,94.1167],'a15':[24.8167,92.8],'a16':[24.75,84.95],
'a17':[25.6,85.1],'a18':[30.7333,76.75],'a19':[21.2333,81.6333],'a20':[20.2833,73],
'a21':[20.4167,72.85],'a22':[28.7833,77.0333],'a23':[28.5667,77.1167],'a24':[15.3833,73.8167],
'a25':[15.3833,73.8167],'a26':[23.0333,72.6167],'a27':[21.75,72.2],'a28':[23.25,69.6667],
'a29':[23.3333,72.5833],'a30':[22.4667,70.0667],'a31':[23.0333,70.2167],'a32':[22.3,70.7833],
'a33':[22.3,73.2667],'a34':[29.1667,75.7333],'a35':[31.25,76.6667],'a36':[32.2,76.4],
'a37':[31.9667,77.1],'a38':[31.1,77.1667],'a39':[32.7,74.8667],'a40':[34.0833,74.8167],
'a41':[22.8167,86.1833],'a42':[23.3167,85.3167],'a43':[12.9833,77.5833],'a44':[15.85,74.6167],
'a45':[15.15,76.85],'a46':[15.35,75.1667],'a47':[12.55,76.9],'a48':[12.9167,74.8833],
'a49':[12.3,76.65],'a50':[9.95,76.2667],'a51':[11.25,75.7667],'a52':[8.46667,76.95],
'a53':[10.9167,72.3333],'a54':[10.5833,72.65],'a55':[23.2833,77.35],'a56':[26.2333,78.2333],
'a57':[22.7167,75.8],'a58':[23.2,79.95],'a59':[21.8333,76.3667],'a60':[24.5667,80.8333],
'a61':[19.0833,74.7333],'a62':[20.7,77.0667],'a63':[19.85,75.4],'a64':[19.8333,75.8833],
'a65':[16.7,74.2333],'a66':[19.1167,72.85],'a67':[21.1,79.05],'a68':[19.8933,73.8],
'a69':[18.55,73.8167],'a70':[18.5333,73.8667],'a71':[17.6667,75.9],'a72':[24.7667,93.9],
'a73':[25.55,91.85],'a74':[23.6667,92.6667],'a75':[25.6667,94.1167],'a76':[20.25,85.8333],
'a77':[21.5833,84.08333],'a78':[10.95,79.7833],'a79':[11.7,75.5333],'a80':[11.9333,79.8833],
'a81':[16.7333,82.2167],'a82':[31.6333,74.8667],'a83':[32.2833,75.65],'a84':[26.8167,75.8],
'a85':[29.1667,75.7333],'a86':[25.15,75.85],'a87':[24.5667,73.6167],'a88':[27.3333,88.6167],
'a89':[13,80.1833],'a90':[11.0333,77.05],'a91':[9.83333,78.0833],'a92':[8.16667,77.4333],
'a93':[8.48333,78.1167],'a94':[12.2167,79.0667],'a95':[8.78333,78.1333],'a96':[10.7667,78.7167],
'a97':[8.73333,77.7],'a98':[12.9167,79.15],'a99':[23.8833,91.25],'a100':[27.15,77.9667],
'a101':[25.45,81.7333],'a102':[28.3667,79.4],'a103':[26.75,83.3667],'a104':[29.1667,75.7333],
'a105':[26.4,80.4],'a106':[26.75,80.8833],'a107':[25.45,83],'a108':[30.3167,78.0333],
'a109':[29.0833,79.5],'a110':[22.65,88.45],'a111':[26.6333,88.3167]
}
for eachOne in allData:
for eachTwo in latlongs:
eachOne_Coordinates_Latitude = eachOne['COORDINATES-Latitude']
latlongs_eachTwo_Latitude_Plus = int(latlongs[eachTwo][0]) + 0.18
latlongs_eachTwo_Latitude_Minus = int(latlongs[eachTwo][0]) - 0.18
eachOne_Coordinates_Longitude = eachOne['COORDINATES-Longitude']
latlongs_eachTwo_Longitude_Plus = int(latlongs[eachTwo][1]) + 0.18
latlongs_eachTwo_Longitude_Minus = int(latlongs[eachTwo][1]) - 0.18
if ( (eachOne_Coordinates_Latitude < latlongs_eachTwo_Latitude_Plus) and (latlongs_eachTwo_Latitude_Plus > latlongs_eachTwo_Latitude_Minus) ) and ( (eachOne_Coordinates_Longitude < latlongs_eachTwo_Longitude_Plus) and (eachOne_Coordinates_Longitude > latlongs_eachTwo_Longitude_Minus) ):
someDict.setdefault((eachOne_Coordinates_Latitude,eachOne_Coordinates_Longitude),[]).append(latlongs[eachTwo])
for each in someDict:
print each,':', min(someDict[each])
MY PROBLEM:
As you know, the latitudes and longitudes that we get from external sources does not exactly match with the latitudes and longitudes that we have. I heard somewhere that they wont match and there will be some error percentage or something.
I need some guidance from anyone. I request someone to please point me in the right direction or if you know any packages or scripts that does this.
I would be extremely thankful to you.
This sounds a lot like a "Closest point problem". You have N points (cities) and M locations (your 8000 coordinates). For each of the M locations, you want to categorize the location by its closest city. There are a number of solutions for the Nearest Neighbor Search, but the simplest one is a linear search:
function getClosestCity(Coordinate location){
bestCity = cities[0];
foreach(city in cities){
if (distance(bestCity.location, location) < distance(city.location, location)){
bestCity = city;
}
}
return bestCity;
}

Calculation star position in the sky, PyEphem

I have difficulties with finding current coordinates (RA, DEC) for star in sky.
In net I have found only this one tutorial, how to use ephem library: http://asimpleweblog.wordpress.com/2010/07/04/astrometry-in-python-with-pyephem/
As I understood I need to:
create observer
telescope = ephem.Observer()
telescope.long = ephem.degrees('10')
telescope.lat = ephem.degrees('60')
telescope.elevation = 200
Create a body Object star
here is trouble, I have only (RA,DEC) coordinates for star
Calculate position by .calculate(now())
by new coordinates find altitude
One more question about accuracy of this library, how accurate it is? I have compared juliandate and sidestreal time between this program and kstars, looks like quite similar.
and this http://www.jgiesen.de/astro/astroJS/siderealClock/
PS! Or may be some one can reccomend better library for this purposes.
I guess you're looking for FixedBody?
telescope = ephem.Observer()
telescope.long = ephem.degrees('10')
telescope.lat = ephem.degrees('60')
telescope.elevation = 200
star = ephem.FixedBody()
star._ra = 123.123
star._dec = 45.45
star.compute(telescope)
print star.alt, star.az
I don't know about the accuracy; pyephem uses the same code as xephem, and eg the positions of the planets are given by rounded-down VSOP87 solutions (accuracy better than 1 arcsecond); kstars appears to use the full VSOP solution.
But this will really depend on your need; eg don't rely on it blindly guiding your telescope, there are better solutions for that.
star = ephem.FixedBody(ra=123.123, dec=45.45)
in my case fixedbody creation does not work, should be
star = ephem.FixedBody()
star._ra = ephem.hours('10:10:10')
star._dec = ephem.degrees('10:10:10')

Categories