Create polygons based on GPS-logging points SQL 2008 - sql

I'm using SQL Server 2008 and I want to create a database view in which polygons are created based on points in a results-table?
Some remarks:
The results-table contains i.a. the columns 'ScanID', 'Location', 'Latitude', 'Longitude', 'Automatic'.
The combination of a consecutive series of ScanID's and a value in the column 'Location' should result into unique polygons.
The column 'Automatic' defines whether a specific point should be taken into account (1) or not (0).
The first vertex of the polygon should be repeated in the end of the polygon-string to close the polygon. The results-table only contains GPS-logging points and doesn't repeat the first point.
Some representative sample data:
(7894560, 'Lake', '52.9891', '5.1206', 0),
(7894561, 'Lake', '52.9901', '5.1201', 1),
(7894562, 'Lake', '52.9901', '5.1211', 1),
(7894563, 'Lake', '52.9911', '5.1211', 1),
(7894564, 'Lake', '52.9911', '5.1201', 1),
(7894565, 'House', '52.9901', '5.1211', 1),
(7894566, 'House', '52.9901', '5.1221', 1),
(7894567, 'House', '52.9911', '5.1221', 1),
(7894568, 'House', '52.9911', '5.1211', 1),
(7894569, 'Lake', '52.9901', '5.1221', 1),
(7894570, 'Lake', '52.9901', '5.1231', 1),
(7894571, 'Lake', '52.9911', '5.1231', 1),
(7894572, 'Lake', '52.9911', '5.1221', 1);
Ideally the output would be formatted as follows:
(Location, Shape)
('Lake', 'POLYGON (52.9890 5.1201, 52.9901 5.1211, 52.9911 5.1211, 52.9911 5.1201, 52.9890 5.1201)')
('House', 'POLYGON (52.9901 5.1211, 52.9901 5.1221, 52.9911 5.1221, 52.9911 5.1211, 52.9901 5.1211)')
('Lake', 'POLYGON (52.9901 5.1221, 52.9901 5.1231, 52.9911 5.1231, 52.9911 5.1221, 52.9901 5.1221)')
I've got another database view in which I create linestrings by taking two consecutive points. The code I use there is:
GEOMETRY::STGeomFromText('LINESTRING(' + CONVERT(VARCHAR,
CAST(t1.latitude AS decimal(20, 16))) + ' ' + CONVERT(VARCHAR, CAST(t1.longitude AS decimal(20, 16))) + ', ' + CONVERT(VARCHAR, CAST(t2.latitude AS decimal(20, 16)))
+ ' ' + CONVERT(VARCHAR, CAST(t2.longitude AS decimal(20, 16))) + ')', 4326) AS Shape"
I don't think I should solve my problem by using and transforming this piece of code, but it gives some direction. Probably de piece 'GEOMETRY::STGeomFromText' or something like that should be used.
Thanks in advance!

Related

VBA Word - Text form fields in table

I need to add form field with to every cell in a table. Here is what I have so far.
Set csvTable = ActiveDocument.Tables(2)
With csvTable
For r = 1 To UBound(csvData)
.cell(r + 4, 1).Range.FormFields.Add(Range:=.cell(r + 4, 1).Range, Type:=wdFieldFormTextInput).Result = csvData(r)(0)
.cell(r + 4, 3).Range.FormFields.Add(Range:=.cell(r + 4, 3).Range, Type:=wdFieldFormTextInput).Result = csvData(r)(3)
.cell(r + 4, 5).Range.FormFields.Add(Range:=.cell(r + 4, 5).Range, Type:=wdFieldFormTextInput).Result = csvData(r)(4)
.cell(r + 4, 4).Range.FormFields.Add(Range:=.cell(r + 4, 5).Range, Type:=wdFieldFormTextInput).Result = csvData(r)(5)
.cell(r + 4, 5).Range.FormFields.Add(Range:=.cell(r + 4, 5).Range, Type:=wdFieldFormTextInput).Result = csvData(r)(6)
Next
End With
The code seems to add form fields as wanted to all the cells, but the text added ends up only in the first column (i.e. for each row, the text is iteratively updated in the first column only and I end up with csvData(r)(6) in the first column of each row). Any help would be appreciated!

Getting an integer value from dates VBA

I am trying to get a value difference (integer) between the years of 2 different dates in VBA and take also month (for example 2020 - 2019, the result I would want is 1) but my code only give me a date. Any ideas?
For i = 2 To PnLD1WS.Cells(1, 1).End(xlDown).Row
PnLD1WS.Cells(i, 164).Value = ((((DateSerial(Year(PnLD1WS.Cells(i, 13)), 0, 0) - DateSerial(Year(PnLD1WS.Cells(i, 3)), 0, 0)) * 12) + (DateSerial(0, (Month(PnLD1WS.Cells(i, 13))), 0) - (DateSerial(0, (Month(PnLD1WS.Cells(i, 3))), 0)))))
Next i
You can use DateDiff:
DateDiff("yyyy", dat1, dat2)
With your code:
...
With PnLD1WS
.Cells(i, 164).Value = DateDiff("yyyy", .Cells(i, 13), PnLD1WS.Cells(i, 3))
End with
....

Performing a mod function on time data column pandas python

Hello I wanted to apply a mod function of column % 24 to the hour of time column.
I believe the time column is in a string format,
I was wondering how I should go about performing the operation.
sales_id,date,time,shopping_cart,price,parcel_size,Customer_lat,Customer_long,isLoyaltyProgram,nearest_storehouse_id,nearest_storehouse,dist_to_nearest_storehouse,delivery_cost
ORD0056604,24/03/2021,45:13:45,"[('bed', 3), ('Chair', 1), ('wardrobe', 4), ('side_table', 2), ('Dining_table', 2), ('mattress', 1)]",3152.77,medium,-38.246,145.61984,1,4,Sunshine,78.43,5.8725000000000005
ORD0096594,13/12/2018,54:22:20,"[('Study_table', 4), ('wardrobe', 4), ('side_table', 1), ('Dining_table', 2), ('sofa', 4), ('Chair', 3), ('mattress', 1)]",3781.38,large,-38.15718,145.05072,1,4,Sunshine,40.09,5.8725000000000005
ORD0046310,16/02/2018,17:23:36,"[('mattress', 2), ('wardrobe', 1), ('side_table', 2), ('sofa', 1), ('Chair', 3), ('Study_table', 4)]",2219.09,medium,144.69623,-38.00731,0,2,Footscray,34.2,16.9875
ORD0031675,25/06/2018,17:38:48,"[('bed', 4), ('side_table', 1), ('Chair', 1), ('mattress', 3), ('Dining_table', 2), ('sofa', 2), ('wardrobe', 2)]",4542.1,large,144.65506,-38.40669,1,2,Footscray,72.72,18.274500000000003
ORD0019799,05/01/2021,18:37:16,"[('wardrobe', 1), ('Study_table', 3), ('sofa', 4), ('side_table', 2), ('Chair', 4), ('Dining_table', 4), ('bed', 1)]",3132.71,L,-37.66022,144.94286,1,0,Clayton,17.77,14.931
ORD0041462,25/12/2018,07:29:33,"[('Chair', 3), ('bed', 1), ('mattress', 3), ('side_table', 3), ('wardrobe', 3), ('sofa', 4)]",4416.42,medium,-38.39154,145.87448,0,6,Sunshine,105.91,6.151500000000001
ORD0047848,30/07/2021,34:18:01,"[('Chair', 3), ('bed', 3), ('wardrobe', 4)]",2541.04,small,-37.4654,144.45832,1,2,Footscray,60.85,18.4635
Convert values to timedeltas by to_timedelta and then remove days by indexing - selecting last 8 values:
print (df)
sales_id date time
0 ORD0056604 24/03/2021 45:13:45
1 ORD0096594 13/12/2018 54:22:20
print (pd.to_timedelta(df['time']))
0 1 days 21:13:45
1 2 days 06:22:20
Name: time, dtype: timedelta64[ns]
df['time'] = pd.to_timedelta(df['time']).astype(str).str[-8:]
print (df)
sales_id date time
0 ORD0056604 24/03/2021 21:13:45
1 ORD0096594 13/12/2018 06:22:20
If need also add days to date column solution is add timedeltas to dates and last extract values by Series.dt.strftime:
dates = pd.to_datetime(df['date'], dayfirst=True) + pd.to_timedelta(df['time'])
df['time'] = dates.dt.strftime('%H:%M:%S')
df['date'] = dates.dt.strftime('%d/%m/%Y')
print (df)
sales_id date time
0 ORD0056604 25/03/2021 21:13:45
1 ORD0096594 15/12/2018 06:22:20

Replacement (Hyperlinks.Add Anchor)

Is there such a command/method in VBA that operated the same way as
Hyperlinks.Add Anchor , but worked with variables , not with ranges ?
book1.ActiveSheet.Hyperlinks.Add Anchor:=Cells(34 + (x - 1), (26 + (iLoop * 21)) + (y - 1)), Address:=data(x, y), TextToDisplay:=vata(x, y)
That instead of
Cells(34 + (x - 1), (26 + (iLoop * 21)) + (y - 1))
there was a variable .

Data handling for matplotlib histogram with error bars

I've got a data set which is a list of tuples in python like this:
dataSet = [(6.1248199999999997, 27), (6.4400500000000003, 4), (5.9150600000000004, 1), (5.5388400000000004, 38), (5.82559, 1), (7.6892199999999997, 2), (6.9047799999999997, 1), (6.3516300000000001, 76), (6.5168699999999999, 1), (7.4382099999999998, 1), (5.4493299999999998, 1), (5.6254099999999996, 1), (6.3227700000000002, 1), (5.3321899999999998, 11), (6.7402300000000004, 4), (7.6701499999999996, 1), (5.4589400000000001, 3), (6.3089700000000004, 1), (6.5926099999999996, 2), (6.0003000000000002, 5), (5.9845800000000002, 1), (6.4967499999999996, 2), (6.51227, 6), (7.0302600000000002, 1), (5.7271200000000002, 49), (7.5311300000000001, 7), (5.9495800000000001, 2), (5.1487299999999996, 18), (5.7637099999999997, 6), (5.5144500000000001, 44), (6.7988499999999998, 1), (5.2578399999999998, 1)]
Where the first element of the tuple is an energy and the second a counter, how many sensor where affected.
I want to create a histogram to study the relation between the number of affected sensors and the energy. I'm pretty new to matplotlib (and python), but this is what I've done so far:
import math
import matplotlib.pyplot as plt
dataSet = [(6.1248199999999997, 27), (6.4400500000000003, 4), (5.9150600000000004, 1), (5.5388400000000004, 38), (5.82559, 1), (7.6892199999999997, 2), (6.9047799999999997, 1), (6.3516300000000001, 76), (6.5168699999999999, 1), (7.4382099999999998, 1), (5.4493299999999998, 1), (5.6254099999999996, 1), (6.3227700000000002, 1), (5.3321899999999998, 11), (6.7402300000000004, 4), (7.6701499999999996, 1), (5.4589400000000001, 3), (6.3089700000000004, 1), (6.5926099999999996, 2), (6.0003000000000002, 5), (5.9845800000000002, 1), (6.4967499999999996, 2), (6.51227, 6), (7.0302600000000002, 1), (5.7271200000000002, 49), (7.5311300000000001, 7), (5.9495800000000001, 2), (5.1487299999999996, 18), (5.7637099999999997, 6), (5.5144500000000001, 44), (6.7988499999999998, 1), (5.2578399999999998, 1)]
binWidth = .2
binnedDataSet = []
#create another list and append the "binning-value"
for item in dataSet:
binnedDataSet.append((item[0], item[1], math.floor(item[0]/binWidth)*binWidth))
energies, sensorHits, binnedEnergy = [[q[i] for q in binnedDataSet] for i in (0,1,2)]
plt.plot(binnedEnergy, sensorHits, 'ro')
plt.show()
This works so far (although it doesn't even look like a histogram ;-) but OK), but now I want to calculate the mean value for each bin and append some error bars.
What's the way to do it? I looked at histogram examples for matplotlib, but they all use one-dimensional data which will be counted, so you get a frequency spectrum… That's not really what I want.
I am somewhat confused by exactly what you are trying to do, but I think this (to first order) will do what I think you want:
bin_width = .2
bottom = 5.0
top = 8.0
binned_data = [0.0] * int(math.ceil(((top - bottom) / bin_width)))
binned_count = [0] * int(math.ceil(((top - bottom) / bin_width)))
n_bins = len(binned_data)
for E, cnt in dataSet:
if E < bottom or E > top:
print 'out of range'
continue
bin_id = int(math.floor(n_bins * (E - bottom) / (top - bottom)))
binned_data[bin_id] += cnt
binned_count[bin_id] += 1
binned_avergaed_data = [C_sum / hits if hits > 0 else 0 for C_sum, hits in zip(binned_data, binned_count)]
bin_edges = [bottom + j * bin_width for j in range(len(binned_data))]
plt.bar(bin_edges, binned_avergaed_data, width=bin_width)
I would also suggest looking into numpy, it would make this much simpler to write.