Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / Microsoft SQL Server Новый топик    Ответить
 Подскажите с полигонами  [new]
sts7865
Guest
Решил продолжить в новой теме, т.к. в прежней Подскажите с апдейтом криво задал вопрос.
Итак, есть исходные полигоны, (в примере 3, но м.б. больше), надо найти их пересечения, а из исходных вычесть полигоны пересечений.
В примере, пересечения я получил, их получилось по 2 на исходный объект, а как теперь подрезать исходные???
Или я вообще не тем путем пошел...
 Declare @samples table  (id int IDENTITY(1,1) NOT NULL primary key, val geometry, id1 int, id2 int, lvl int);																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																															

INSERT INTO @samples values																										
   (geometry::STPolyFromText('POLYGON((	 1870.9036 2319.5399	,	 2218.3697 3078.8178	,	 2964.7784 2975.8648	,	 3157.8151 2319.5399	,	 2308.4535 2010.6812	,	 2282.7153 2525.4458	,	 1999.5947 2255.1944	,	 1729.3433 1830.5135	,	 1047.2802 2126.5032	,	 1870.9036 2319.5399	,	 1870.9036 2319.5399	))', 4326),	0	,0	,	1	),
   (geometry::STPolyFromText('POLYGON((	 1332.2542 2691.2805	,	 2125.0001 2535.8401	,	 2347.7980 2784.5447	,	 2679.4042 3416.6689	,	 2384.0674 3675.7362	,	 1555.0521 3618.7414	,	 1181.9952 3271.5912	,	 1166.4511 2836.3581	,	 1332.2542 2691.2805			,	 1332.2542 2691.2805	))', 4326),	0	,0	,	1	),
   (geometry::STPolyFromText('POLYGON((	 2062.8240 3706.8243	,	 2176.8136 2831.1768	,	 2679.4042 2727.5499	,	 3244.1709 2794.9074	,	 3321.8911 3447.7570	,	 2451.4249 3763.8191	,	 2062.8240 3706.8243							,	 2062.8240 3706.8243	))', 4326),	0	,0	,	1	)

-- ищем все пересечения объектов и пишем их с индексом следующего уровня
Declare @level int = 1;
INSERT INTO @samples
SELECT s.geo, s.parent1, s.parent2, @level+1 from
(
	SELECT s1.val.MakeValid().STIntersection(s2.val.MakeValid()) as geo, s1.id as parent1, s2.id as parent2
	FROM @samples s1 inner join 
		 @samples s2 on (s2.id > s1.id)
	where ((s1.lvl=@level)and(s2.lvl=@level))
) as s
Where s.geo.ToString() <> 'GEOMETRYCOLLECTION EMPTY'

SELECT * FROM @samples where lvl=1
SELECT * FROM @samples where lvl=2
14 июн 13, 15:53    [14434521]     Ответить | Цитировать Сообщить модератору
 Re: Подскажите с полигонами  [new]
Mnior
Member

Откуда: Кишинёв
Сообщений: 6724
Как вы хотите подрезать? A(I)B
1. A-I, B
2. A, B-I
3. A-I,B-I
?

 ... val.MakeValid() ...
Where s.geo.ToString() <> 'GEOMETRYCOLLECTION EMPTY'
Вы не программист вы быдлокодер. Фу
SELECT FROM (SELECT FROM (SELECT ...))
Адепт лиспа?
Есть такой оператор - APPLY
14 июн 13, 18:04    [14435127]     Ответить | Цитировать Сообщить модератору
 Re: Подскажите с полигонами  [new]
Mnior
Member

Откуда: Кишинёв
Сообщений: 6724
STDifference
14 июн 13, 18:31    [14435191]     Ответить | Цитировать Сообщить модератору
 Re: Подскажите с полигонами  [new]
sts7865
Guest
Mnior,
Я не претендую на звание суперкодера :) тем более в TSQL, тем более это просто пример сделанный на коленке. И про то что SELECT FROM (SELECT ... - не кошерно тож в курсе, просто первое что пришло, чтобы отсечь пустые геометрии, получающиеся после STIntersection. Спасибо за APPLY, посмотрю. про STDifference - знаю.
А вычесть хочу из каждого исходного все его пересечения с остальными исходными. т.е. это, наверное вариант 3. A-I,B-I
спасибо.
15 июн 13, 10:33    [14436584]     Ответить | Цитировать Сообщить модератору
 Re: Подскажите с полигонами  [new]
Mnior
Member

Откуда: Кишинёв
Сообщений: 6724
sts7865
Я не претендую на звание суперкодера :) тем более в TSQL, тем более это просто пример сделанный на коленке. И про то что SELECT FROM (SELECT ... - не кошерно тож в курсе
Проблема в том что вы это себе позволяете.
Просто никогда не делайте не правильно, даже "на коленке". Это входит в привычку и вы по другому как "на коленке" не сможете в принципе никогда.
sts7865
просто первое что пришло, чтобы отсечь пустые геометрии, получающиеся после STIntersection.
Метод последовательно разделяй в властвуй в мышлении?! Боже. Задачу надо видеть и чувствовать. Жалко калории потратить? Не бойтесь моск не сотрётся, не железный.
sts7865
A-I,B-I
Т.е. найти все уникальные области.

Да многими способами можно.
DECLARE @Poly TABLE (ID Int IDENTITY PRIMARY KEY, geo geometry);

INSERT @Poly (geo) OUTPUT Inserted.* VALUES
 (geometry::STPolyFromText('POLYGON((1870.9036 2319.5399,2218.3697 3078.8178,2964.7784 2975.8648,3157.8151 2319.5399,2308.4535 2010.6812,2282.7153 2525.4458,1999.5947 2255.1944,1729.3433 1830.5135,1047.2802 2126.5032,1870.9036 2319.5399,1870.9036 2319.5399))'	,0))
,(geometry::STPolyFromText('POLYGON((1332.2542 2691.2805,2125.0001 2535.8401,2347.7980 2784.5447,2679.4042 3416.6689,2384.0674 3675.7362,1555.0521 3618.7414,1181.9952 3271.5912,1166.4511 2836.3581,1332.2542 2691.2805,1332.2542 2691.2805))'				,0))
,(geometry::STPolyFromText('POLYGON((2062.8240 3706.8243,2176.8136 2831.1768,2679.4042 2727.5499,3244.1709 2794.9074,3321.8911 3447.7570,2451.4249 3763.8191,2062.8240 3706.8243,2062.8240 3706.8243))'									,0))

;WITH [Result] (ID,[Union],[Intersect]) AS (
	SELECT	 ID
		,geo
		,geometry::STGeomFromText('GEOMETRYCOLLECTION EMPTY',0)
	FROM	@Poly	P
	WHERE	P.ID = 1
UNION ALL
	SELECT	 N.ID
		,P.[Union].STUnion(N.geo)
		,P.[Intersect].STUnion(P.[Union].STIntersection(N.geo))
	FROM	[Result]P
	JOIN	@Poly	N ON N.ID = P.ID + 1
)	SELECT	Top(1) R.[Union].STDifference(R.[Intersect]),R.*
	FROM	[Result]	R
	ORDER BY R.ID Desc
Mnior
STDifference
STSymDifference как раз и есть (A-I,B-I)
16 июн 13, 01:57    [14438032]     Ответить | Цитировать Сообщить модератору
Все форумы / Microsoft SQL Server Ответить