Obracanie warstwy wektorowej w QGIS za pomocą qgsAffine (lub innej metody)?

10

Chciałbym obrócić zestaw punktów wektorowych w QGIS o dowolną liczbę stopni wokół punktu centralnego (lub dowolnego punktu).

Jest to podobne do ostatniego pytania dotyczącego tworzenia regularnej siatki ; zasugerowano, aby użyć narzędzia „Affine Transformation” (co, jak zakładam, oznaczało wtyczkę), aby obrócić lub przesunąć siatkę punktów o dowolny kąt lub odległość. Podejrzewam, że nie rozumiem, jak to działa, i nie byłem w stanie sprawić, by działał.

Tworzę regularną siatkę punktów w QGIS i upewniam się, że strefa UTM jest ustawiona poprawnie zarówno dla warstwy, jak i projektu, włączam edycję dla warstwy, a następnie otwieram okno dialogowe wtyczki (qgsAffine): Okno dialogowe Transformacja afiniczna

Wybieram „całą warstwę”, a następnie, chcąc obrócić całe pole punktów o 15 °, umieszczam 15 w obu polach „obrotu” (które mogą być tam, gdzie dzieje się źle). Operacja powoduje obrócenie punktów gdzieś poza planetą!

Czy to odpowiednie narzędzie do pracy? Idealnie chciałbym obrócić zestaw punktów dotyczących ich wspólnego centrum.

Aktualizacja : qgsAffine to tylko myśl; jeśli możemy to zrobić w dowolnym narzędziu QGIS, będę szczęśliwy!

Aktualizacja 2 : qgsAffine jest użyteczny, JEŻELI znasz odpowiednie numery do podłączenia (patrz odpowiedź poniżej, dziękuję Mike!). Arkusz kalkulacyjny / kalkulator działa dobrze, lub oto funkcja R, aby uzyskać liczby bezpośrednio:

## Compute correct affine numbers for qgsAffine plugin
affine <- function(originX, originY, rotAngle) {
  A <- rotAngle * pi / 180
  scaleX <- scaleY <- cos(A)
  rotX <- sin(A)
  rotY <- -sin(A)
  transX <- originX - cos(A) * originX + sin(A) * originY
  transY <- originY - sin(A) * originX - cos(A) * originY
  aff <- data.frame(scaleX, scaleY, rotX, rotY, transX, transY)
  return(aff)
}

Tak więc obrócenie siatki punktów w północnej Ugandzie (UTM 36N) affine(578988, 419210, 30)daje:

     scaleX    scaleY rotX rotY   transX    transY
1 0.8660254 0.8660254  0.5 -0.5 287174.7 -233330.5

... które, wprowadzone w oknie dialogowym qgsAffine, poprawnie obraca punkty.

Simbamangu
źródło
niezła adaptacja R.
Mike T

Odpowiedzi:

10

Możesz to zrobić w PostGIS za pomocą ST_Affine . Funkcję obracania wokół dowolnego punktu dodano do ST_Rotate dla PostGIS 2.0.

Jeśli masz wcześniejszą wersję (np. PostGIS 1.5 lub nawet wcześniejszą), możesz dodać te funkcje:

CREATE OR REPLACE FUNCTION st_rotate(geometry, double precision, geometry)
  RETURNS geometry AS
'SELECT ST_Affine($1,  cos($2), -sin($2), 0,  sin($2),  cos($2), 0, 0, 0, 1, ST_X($3) - cos($2) * ST_X($3) + sin($2) * ST_Y($3), ST_Y($3) - sin($2) * ST_X($3) - cos($2) * ST_Y($3), 0)'
  LANGUAGE sql IMMUTABLE STRICT
  COST 100;
COMMENT ON FUNCTION st_rotate(geometry, double precision, geometry) IS 'args: geomA, rotRadians, pointOrigin - Rotate a geometry rotRadians counter-clockwise about an origin.';

CREATE OR REPLACE FUNCTION st_rotate(geometry, double precision, double precision, double precision)
  RETURNS geometry AS
'SELECT ST_Affine($1,  cos($2), -sin($2), 0,  sin($2),  cos($2), 0, 0, 0, 1,    $3 - cos($2) * $3 + sin($2) * $4, $4 - sin($2) * $3 - cos($2) * $4, 0)'
  LANGUAGE sql IMMUTABLE STRICT
  COST 100;
COMMENT ON FUNCTION st_rotate(geometry, double precision, double precision, double precision) IS 'args: geomA, rotRadians, x0, y0 - Rotate a geometry rotRadians counter-clockwise about an origin.';

Zobacz przykłady na ST_Rotate , aby zorientować się, w jaki sposób używać go obrócić geometrię wokół x , y punktu, w tym centrum ciężkości (wspólny).

Ponieważ wszyscy lubimy matematykę, macierz transformacji z powyższych funkcji jest reprezentowana jako:

[ cos(θ)  | -sin(θ)  ||  x0 - cos(θ) * x0 + sin(θ) * y0 ]
[ sin(θ)  |  cos(θ)  ||  y0 - sin(θ) * x0 - cos(θ) * y0 ]

Gdzie θ to obrót w kierunku przeciwnym do ruchu wskazówek zegara wokół początku, x0 to wschód / długość geograficzna punktu początkowego, a y0 to północ / szerokość geograficzna. Ta matematyka mogłaby zostać zaadaptowana do dowolnego narzędzia transformacji afinicznej.


Aby skorzystać z narzędzia qgsAffine, musisz zrozumieć, dokąd płyną wartości macierzy. Dobry szablon arkusza kalkulacyjnego jest również wymagany do wykonywania wstępnych obliczeń. Okno dialogowe qgsAffine wygląda mniej więcej tak:

              X   Y
            +---+---+
      Scale | a | e |
            +---+---+
   Rotation | d | b |
            +---+---+
Translation | c | f |
            +---+---+

gdzie:

  • a : cos (θ)
  • b : -sin (θ)
  • c : x0 - cos (θ) * x0 + sin (θ) * y0
  • d : sin (θ)
  • e : cos (θ)
  • f : y0 - sin (θ) * x0 - cos (θ) * y0

Na przykład, jeśli chcesz obrócić wielokąt o 30 ° zgodnie z ruchem wskazówek zegara wokół 42 ° S, 174 ° E, oto dane wejściowe do arkusza kalkulacyjnego:

  • x0 = 174
  • y0 = -42
  • θ = -30 stopni lub -0,523598776 radianów

Następnie skopiuj / wklej wyniki z arkusza kalkulacyjnego do prawego pola. Za pomocą kolejności kart w oknie dialogowym:

  • a: 0,866025404
  • d: -0,5
  • c: 44,31157974
  • e: 0,866025404
  • b: 0,5
  • f: 81,37306696

qgsAffine

Ten sam przykład z PostGIS wyglądałby mniej więcej tak:

SELECT ST_Rotate(geom, -30*pi()/180, 174.0, -42.0)
Mike T.
źródło
To wygląda całkiem nieźle; jeśli możemy to zrobić w Spatialite, kwalifikowałoby się to jako „robienie tego w QGIS”, ponieważ możemy uruchomić SQL na plikach Spatialite poprzez wtyczki QGIS; PostGIS będzie kolejnym krokiem w instalacji dla użytkowników, do których nie chcę wchodzić. Masz pojęcie, czy jakieś funkcje przestrzenne mogą również obracać się wokół środka ciężkości?
Simbamangu,
aha, odszyfrowałem qgsAffine, działa teraz zgodnie z oczekiwaniami ... tylko dużo kopiowania / wklejania z arkusza kalkulacyjnego
Mike T
Mike, to działa dobrze! Spróbuję również sprawić, aby ta praca działała również w Spatialite (PostGIS / spatialite sprawiają, że te operacje są o wiele łatwiejsze), ale przynajmniej teraz mogę uruchomić qgsAffine i przynajmniej jest to prosta wtyczka.
Simbamangu,
Próbowałem dostosować go do JavaScript: zobacz tutaj , także jsfiddle
flackend
1
Obliczając powyższą funkcję javascript Udało mi się z powodzeniem obliczyć parametry afiniczne i obrócić niektóre wektory, ale nie jest to tak przyjazne dla użytkownika: musisz użyć wtyczki przechwytywania współrzędnych, aby uzyskać współrzędne środka obrotu, a następnie obliczyć parametry transformacji i skopiować i wkleić z powrotem do QGis! Byłoby znacznie łatwiej, gdyby sama wtyczka wykonała obliczenia, a użytkownicy po prostu kliknęli, aby wprowadzić współrzędne środka obrotu i zdefiniować kąt obrotu.
bradypus
2

Nigdzie nie próbowałem obracać warstw wektorowych za pomocą qgsAffine i myślę, że nie jestem sam. To pytanie pojawiło się ostatnio na forum QGIS i znaleziono rozwiązanie, używając (darmowego) OpenJump. Spójrz na ten wątek (pod koniec):

http://forum.qgis.org/viewtopic.php?f=2&t=10126&sid=28473d53d244a4cd2a6f91887811ef02

Oczywiście możesz również użyć tego narzędzia, aby wykonać prosty obrót danych.

nhopton
źródło