创建一个Abitrary,弯曲的Well Known Text LineString,用于在OpenLayers中显示 [英] Creating an abitrary, curved Well Known Text LineString for display in OpenLayers

查看:354
本文介绍了创建一个Abitrary,弯曲的Well Known Text LineString,用于在OpenLayers中显示的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在生成的地图图层中的点之间动态生成WKT LineString,以便在OpenLayers中显示。我想让曲线之间的线条变成曲线,我希望能够根据各种输入变量动态改变曲率。

这是一个网络监控应用程序,我们希望曲线基于点之间的延迟时间(不是原始延迟本身,而是偏离正常值)。

一些GIS应用程序和数据库支持WKT的 CircularString 扩展名,OpenLayers不知道任何事情。



因此,我需要生成一条线段以外的曲线:



现在,行字符串很简单:

 
LINESTRING(hop1_long hop1_lat,hop2_long hop2_lat)


$ $ b $ p
$ b $ p
LINESTRING(hop1_long)
$ p
LINESTRING(hop1_long)b $ b

hop1_lat,long1 lat1,long2 lat2,...,hop2_long hop2_lat)

这应该完全适合我们的应用程序,我知道如何生成中间点!



我假设有一些众所周知的方法/算法用于在2D平面中生成线段之外的弯曲线。有没有人有任何想法,如何做到这一点,或书籍/文章/在线资源可能有帮助?

UPDATE(2010-08-13) : b
$ b 贝塞尔曲线是票据,读完它后实现基本的贝塞尔算法非常容易。但是我必须编写一些代码来生成控制点。这是我提出的PHP代码。这假设一个Vector2d类,其中 x y 成员。

 
函数get_control_points($ to,$ from,$ mag_scale,$ angle){
$ dirX = $ to> x - $ from-> x;
$ dirY = $ to> y - $ from-> y;

$ mag = sqrt(($ dirX * $ dirX)+($ dirY * $ dirY));
if(!$ mag){
返回数组($ to,$ from);
}

$ length = $ mag * $ mag_scale;

$ dirX = $ dirX / $ mag;
$ dirY = $ dirY / $ mag;

$ sin = sin($ angle);
$ cos = cos($ angle);

$ rotX = $ cos * $ dirX - $ sin * $ dirY;
$ rotY = $ sin * $ dirX + $ cos * $ dirY;
$ rotNegX = $ cos * - $ dirX - $ sin * $ dirY;
$ rotNegY = $ sin * $ dirX - $ cos * $ dirY;

//将控制点翻转为向后曲线
if($ dirX x;
$ y1 = - $ rotNegY * $ length + $ from-> y;
$ x2 = - $ rotX * $ length + $ to> x;
$ y2 = - $ rotY * $ length + $ to> y;
}
// Or生成正常控制点
else {
$ x1 = $ rotX * $ length + $ from-> x;
$ y1 = $ rotY * $ length + $ from-> y;
$ x2 = $ rotNegX * $ length + $ to> x;
$ y2 = $ rotNegY * $ length + $ to> y;
}

返回数组(新的Vector2d($ x2,$ y2),新的Vector2d($ x1,$ y1));
}



其中t的运行范围为0到2π。



所以你可以创建例如通过评估在值t = k =π/ 2; k / 30处的圆来形成半圆形,其中k从0到30运行。这将给你一个半圆弧形30个线段中的一个。



如果您需要更多的一般曲线,请查看贝塞尔曲线。它们通过值t来参数化,可以在0和1之间的统一间隔内评估值。


I am dynamically generating a WKT LineString between points in a map layer being generated for display in OpenLayers. I'd like to make the lines between the points curved, and I'd like to be able to dynamically change the curvature based on various input variables.

This is for a network monitoring app, and we'd like the curvature to based on delay times between the points (not the raw delay itself, but the deviation from "normal" values during a given time period).

While some GIS app and databases support a CircularString extension to WKT, OpenLayers doesn't know anything 'bout that.

So I'll need to generate a curved line out of line segments:

Right now, the line strings are simply:

LINESTRING(hop1_long hop1_lat, hop2_long hop2_lat)

The only way I can determine to make the linesegment "curved" is to insert intermediary points:

LINESTRING(hop1_long hop1_lat, long1 lat1, long2 lat2, ..., hop2_long hop2_lat)

This should be perfectly adequate for our application, but I don't know how to generate the intermediary points!

I assume there are well-known methods/algorithms for generating a "curved" line out of line segments in a 2d plane. Does anyone have any ideas as to how to accomplish this, or books/articles/online resources that could be helpful?

UPDATE (2010-08-13):

Bezier curves were the ticket, and implementing the basic Bezier algorithm was pretty easy after reading up on it. But I had to write some code to generate the control points. Here's the PHP code I came up with. This assumes a "Vector2d" class with x and y members.

function get_control_points($to, $from, $mag_scale, $angle) {
  $dirX = $to->x - $from->x;
  $dirY = $to->y - $from->y;

  $mag = sqrt(($dirX * $dirX) + ($dirY * $dirY));
  if (!$mag) {
    return array($to, $from);
  }

  $length = $mag * $mag_scale;

  $dirX = $dirX / $mag;
  $dirY = $dirY / $mag;

  $sin = sin($angle);
  $cos = cos($angle);

  $rotX = $cos * $dirX - $sin * $dirY;
  $rotY = $sin * $dirX + $cos * $dirY;
  $rotNegX = $cos * -$dirX - $sin * $dirY;
  $rotNegY = $sin * $dirX - $cos * $dirY;

  // Flip control points for "backwards" curves
  if ($dirX x;
    $y1 = -$rotNegY * $length + $from->y;
    $x2 = -$rotX * $length + $to->x;
    $y2 = -$rotY * $length + $to->y;
  }
  // Or generate "normal" control points
  else {
    $x1 = $rotX * $length + $from->x;
    $y1 = $rotY * $length + $from->y;
    $x2 = $rotNegX * $length + $to->x;
    $y2 = $rotNegY * $length + $to->y;
  }

  return array(new Vector2d($x2, $y2), new Vector2d($x1, $y1));
}

解决方案

If you'd like to generate a series of line segments that make a curve, start by looking at curves that are easily parameterized by a single variable. For example, a circle centered at (cx,cy) with radius r is parameterized by the following expression:

(x,y) = (cx,cy)+r*(cos(t), sin(t)),

where t runs from 0 to 2π.

So you could create a semi-circular shape by, say, evaluating the circle at values tk=π×k/30, where k runs from 0 to 30. This would give you a semi-circular arc made out of 30 line segments.

If you want more general curves, check out Bezier curves. They are parameterized by a value t that can be evaluated at uniform intervals between 0 and 1.

这篇关于创建一个Abitrary,弯曲的Well Known Text LineString,用于在OpenLayers中显示的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆