kopia lustrzana https://github.com/lightaprs/LightAPRS-W-1.0
187 wiersze
5.6 KiB
C++
Executable File
187 wiersze
5.6 KiB
C++
Executable File
/*
|
|
* GEOFENCE.c
|
|
*
|
|
* Created: 5.11.2016 22:04:58
|
|
* Author: Tomy2
|
|
*/
|
|
|
|
|
|
#include "GEOFENCE.h"
|
|
|
|
|
|
/*
|
|
Adapted version of pointInPolygon() function from: http://alienryderflex.com/polygon/
|
|
|
|
Returns '0' if the point is outside of the polygon and '1' if it's inside.
|
|
|
|
Expects input DEGREES * 100000 for latitude and longitude. Eg 4961070 for 49.61070 N.
|
|
The reason is to make sure all calculations fit inside int32_t.
|
|
|
|
However, this function is not very accurate due to rounding within the computation.
|
|
*/
|
|
int32_t pointInPolygon(int32_t polyCorners, int32_t * polygon, int32_t latitude, int32_t longitude)
|
|
{
|
|
int32_t i;
|
|
int32_t j = polyCorners * 2 - 2;
|
|
int32_t oddNodes = 0;
|
|
|
|
for(i = 0; i < polyCorners * 2; i += 2)
|
|
{
|
|
if((polygon[i + 1] < latitude && polygon[j + 1] >= latitude
|
|
|| polygon[j + 1] < latitude && polygon[i + 1] >= latitude)
|
|
&& (polygon[i] <= longitude || polygon[j] <= longitude))
|
|
{
|
|
oddNodes ^= (polygon[i] + (latitude - polygon[i + 1])
|
|
/ (polygon[j + 1] - polygon[i + 1]) * (polygon[j] - polygon[i]) < longitude);
|
|
}
|
|
|
|
j = i;
|
|
}
|
|
|
|
return oddNodes;
|
|
}
|
|
|
|
|
|
/*
|
|
Adapted version of pointInPolygon() function from: http://alienryderflex.com/polygon/
|
|
|
|
Returns '0' if the point is outside of the polygon and '1' if it's inside.
|
|
|
|
Uses FLOAT input for better accuracy.
|
|
*/
|
|
int32_t pointInPolygonF(int32_t polyCorners, float * polygon, float latitude, float longitude)
|
|
{
|
|
int32_t i;
|
|
int32_t j = polyCorners * 2 - 2;
|
|
int32_t oddNodes = 0;
|
|
|
|
for(i = 0; i < polyCorners * 2; i += 2)
|
|
{
|
|
if((polygon[i + 1] < latitude && polygon[j + 1] >= latitude
|
|
|| polygon[j + 1] < latitude && polygon[i + 1] >= latitude)
|
|
&& (polygon[i] <= longitude || polygon[j] <= longitude))
|
|
{
|
|
oddNodes ^= (polygon[i] + (latitude - polygon[i + 1])
|
|
/ (polygon[j + 1] - polygon[i + 1]) * (polygon[j] - polygon[i]) < longitude);
|
|
}
|
|
|
|
j = i;
|
|
}
|
|
|
|
return oddNodes;
|
|
}
|
|
|
|
|
|
/*
|
|
Changes GEOFENCE_APRS_frequency and GEOFENCE_no_tx global variables based on the input coordinates.
|
|
|
|
FREQUENCIES:
|
|
Africa 144.800
|
|
Europe 144.800
|
|
Russia 144.800
|
|
Canada 144.390
|
|
Mexico 144.390
|
|
USA 144.390
|
|
Costa Rica 145.010
|
|
Nicaragua 145.010
|
|
Panama 145.010
|
|
Venezuela 145.010
|
|
Brazil 145.570
|
|
Colombia 144.390
|
|
Chile 144.390
|
|
Argentina 144.930
|
|
Paraguay 144.930
|
|
Uruguay 144.930
|
|
China 144.640
|
|
Japan 144.660
|
|
South Korea 144.620
|
|
Thailand 145.525
|
|
Australia 145.175
|
|
New Zealand 144.575
|
|
Indonesia 144.390
|
|
Malaysia 144.390
|
|
|
|
NO AIRBORNE APRS:
|
|
France
|
|
Latvia
|
|
United Kingdom
|
|
|
|
Expected input FLOAT for latitude and longitude as in GPS_UBX_latitude_Float and GPS_UBX_longitude_Float.
|
|
*/
|
|
void GEOFENCE_position(float latitude, float longitude)
|
|
{
|
|
|
|
// SECTOR 1
|
|
if(longitude > -38.0 && longitude < 73.0)
|
|
{
|
|
|
|
// S 1/2
|
|
if(latitude > 0.0)
|
|
{
|
|
if(pointInPolygonF(9, UKF, latitude, longitude) == 1) {GEOFENCE_no_tx = 1;GEOFENCE_APRS_frequency = 144800000;}
|
|
else if(pointInPolygonF(10, LatviaF, latitude, longitude) == 1) {GEOFENCE_no_tx = 1;GEOFENCE_APRS_frequency = 144800000;}
|
|
else {GEOFENCE_no_tx = 0; GEOFENCE_APRS_frequency = 144800000;}
|
|
}
|
|
|
|
// S 2/2
|
|
else
|
|
{
|
|
if(pointInPolygonF(9, BrazilF, latitude, longitude) == 1) {GEOFENCE_no_tx = 0; GEOFENCE_APRS_frequency = 145570000;}
|
|
else {GEOFENCE_no_tx = 0; GEOFENCE_APRS_frequency = 144800000;}
|
|
}
|
|
}
|
|
|
|
// SECTOR 2
|
|
else if(longitude <= -38.0)
|
|
{
|
|
|
|
// S 1/2
|
|
if(latitude > 12.5)
|
|
{
|
|
{GEOFENCE_no_tx = 0; GEOFENCE_APRS_frequency = 144390000;}
|
|
}
|
|
|
|
// S 2/2
|
|
else
|
|
{
|
|
if(pointInPolygonF(8, ArgParUruF, latitude, longitude) == 1) {GEOFENCE_no_tx = 0; GEOFENCE_APRS_frequency = 144930000;}
|
|
else if(pointInPolygonF(9, BrazilF, latitude, longitude) == 1) {GEOFENCE_no_tx = 0; GEOFENCE_APRS_frequency = 145570000;}
|
|
else if(pointInPolygonF(7, VenezuelaF, latitude, longitude) == 1) {GEOFENCE_no_tx = 0; GEOFENCE_APRS_frequency = 145010000;}
|
|
else if(pointInPolygonF(5, CostNicPanF, latitude, longitude) == 1) {GEOFENCE_no_tx = 0; GEOFENCE_APRS_frequency = 145010000;}
|
|
else {GEOFENCE_no_tx = 0; GEOFENCE_APRS_frequency = 144390000;}
|
|
}
|
|
}
|
|
|
|
// SECTOR 3
|
|
else if(longitude >= 73.0)
|
|
{
|
|
|
|
// S 1/2
|
|
if(latitude > 19.2)
|
|
{
|
|
if(pointInPolygonF(12, ChinaF, latitude, longitude) == 1) {GEOFENCE_no_tx = 0; GEOFENCE_APRS_frequency = 144640000;}
|
|
else if(pointInPolygonF(7, JapanF, latitude, longitude) == 1) {GEOFENCE_no_tx = 0; GEOFENCE_APRS_frequency = 144660000;}
|
|
else if(pointInPolygonF(5, South_KoreaF, latitude, longitude) == 1) {GEOFENCE_no_tx = 0; GEOFENCE_APRS_frequency = 144620000;}
|
|
else if(pointInPolygonF(5, ThailandF, latitude, longitude) == 1) {GEOFENCE_no_tx = 0; GEOFENCE_APRS_frequency = 145525000;}
|
|
else {GEOFENCE_no_tx = 0; GEOFENCE_APRS_frequency = 144800000;}
|
|
}
|
|
|
|
// S 2/2
|
|
else
|
|
{
|
|
if(pointInPolygonF(6, AustraliaF, latitude, longitude) == 1) {GEOFENCE_no_tx = 0; GEOFENCE_APRS_frequency = 145175000;}
|
|
else if(pointInPolygonF(5, New_ZealandF, latitude, longitude) == 1) {GEOFENCE_no_tx = 0; GEOFENCE_APRS_frequency = 144575000;}
|
|
else if(pointInPolygonF(5, ThailandF, latitude, longitude) == 1) {GEOFENCE_no_tx = 0; GEOFENCE_APRS_frequency = 145525000;}
|
|
else {GEOFENCE_no_tx = 0; GEOFENCE_APRS_frequency = 144390000;}
|
|
}
|
|
}
|
|
|
|
// shouldn't get here
|
|
else
|
|
{
|
|
{GEOFENCE_no_tx = 0; GEOFENCE_APRS_frequency = 144800000;}
|
|
}
|
|
}
|
|
|
|
|