2008-11-24 38 views
12

Có cách nào tự động tạo một danh sách tương thích HTML-Map các tọa độ của các đối tượng giống như đa giác (ví dụ: các quốc gia trên bản đồ) có đường viền rất khác biệt không?Tạo HTML-Map từ hình ảnh

Ví dụ hình ảnh:

Map of CEE countries http://www.bankaustria.at/landkarten/CEE_2007_w524.jpg

cuối cùng đầu ra:

<map id ="ceemap" name="ceemap"> 
    <area shape="poly" coords="149,303,162,301,162,298,171,293,180,299,169,309,159,306,148,306,149,303" href="austria.html" target ="_blank" alt="Austria" />  
    <!-- ... --> 
</map> 

Bất kỳ công cụ/script giải nén tọa độ của một lựa chọn đa giác giống như sẽ là hữu ích.

Trả lời

8

Mở bản đồ trong Inkscape. Nếu nó là một bitmap, sử dụng Path -> Trace Bitmap để theo dõi các cạnh. Xóa dữ liệu vectơ để chỉ bao gồm các đường dẫn mà bạn muốn xuất hiện trong sơ đồ trang web của mình. Lưu tài liệu, tôi đề nghị một tập tin POVRay. Bây giờ bạn có một danh sách các đỉnh (và rất nhiều đánh dấu hoặc siêu dữ liệu mà bạn không quan tâm) trong một định dạng văn bản thuần túy. Chuyển đổi từ đó sang cú pháp HTML cần thiết vẫn là một vấn đề, nhưng không phức tạp như bước đầu tiên.

Đối với những gì nó có giá trị, có một yêu cầu tính năng lâu dài cho Inkscape bao gồm một tùy chọn để xuất bản đồ hình ảnh HTML.

1

Tôi có thể cung cấp cho bạn một bước của quy trình: bạn sẽ cần phải sử dụng bộ lọc Sobel (thường được gọi là phát hiện cạnh trong các chương trình như Photoshop).

Sau đó, bạn cần phải tìm thư viện theo dõi bằng ngôn ngữ bạn chọn.

10

Cảm ơn sự giúp đỡ của bạn!

Mặc dù Jonathans gợi ý để sử dụng bộ lọc Sobel chắc chắn sẽ làm việc, tôi đã chọn Sparrs cách tiếp cận của đầu tiên chuyển đổi bitmap thành một hình ảnh vector (thông qua Inkscape) và sau đó xử lý các tập tin SVG. Sau khi nghiên cứu một số thông tin cơ bản về đặc tả SVG, thật dễ dàng để trích xuất - đối với các bản đồ hình ảnh HTML cần thiết - tọa độ X/Y từ tất cả các thư rác khác và tạo ra một mã phù hợp.

Mặc dù nó không khoa học tên lửa, ai đó có thể tìm thấy đoạn mã này hữu ích:

// input format: M 166,362.27539 C 163.525,360.86029 161.3875,359.43192 161.25,359.10124 C ... 
private static void Svg2map(string svg_input) 
{ 
    StringBuilder stringToFile = new StringBuilder(); 

    // get rid of some spaces and characters 
    var workingString = svg_input.Replace("z", "").Replace(" M ", "M").Replace(" C ", "C"); 
    // split into seperate polygons 
    var polygons = workingString.Split('M'); 
    foreach (var polygon in polygons) 
    { 
     if (!polygon.Equals(String.Empty)) 
     { 
      // each polygon is a clickable area 
      stringToFile.Append("<area shape=\"poly\" coords=\""); 
      // split into point information 
      var positionInformation = polygon.Split('C'); 
      foreach (var position in positionInformation) 
      { 
       var noise = position.Trim().Split(' '); 
       // only the first x/y-coordinates after C are relevant 
       var point = noise[0].Split(','); 
       foreach (var value in point) 
       { 
        var valueParts = value.Split('.'); 
        // remove part after comma - we don't need this accurancy in HTML 
        stringToFile.Append(valueParts[0]); 
        // comma for seperation - don't worry, we'll clean the last ones within an area out later 
        stringToFile.Append(","); 
       } 
      } 
      stringToFile.AppendLine("\" href=\"targetpage.html\" alt=\"Description\" />"); 
     } 
    } 
    // clean obsolete commas - not pretty nor efficient 
    stringToFile = stringToFile.Replace(",\"", "\""); 

    var fs = new StreamWriter(new FileStream("output.txt", FileMode.Create)); 
    fs.Write(stringToFile.ToString()); 
    fs.Close(); 
} 
+1

xấu hổ tôi không thể xác định những gì ngôn ngữ mà là chỉ cần nhìn vào nó. Câu chuyện 'var' nói javascript, nhưng các tiêu đề trông giống C++ hoặc Java hơn. T.T; là nó C# ??? Có lẽ? – Ziggy

0

tôi đã thực hiện một số thay đổi và thực hiện vào mã của Gerhard Dinhof.

Hàm PHP tạo bản đồ hình ảnh của phối hợp svg được cung cấp. Bạn có thể chỉ định một số yếu tố để thay đổi kích thước số bản dịch khu vực và x-y để căn chỉnh bản đồ với hình ảnh của bạn.

<?php 

/** 
* $str SVG coordinates string 
* $factor number that multiply every coordinate (0-1) 
* $x translation on the x-axis 
* $y translation on the y-axis 
*/ 
function svg2imap($str, $factor=1, $x=0, $y=0) { 

    $res = ""; 

    $str = str_replace(array(" M ","M ", " C "," z "," z"),array("M","M","C","",""), $str); 

    $polygons = explode("M", $str); 

    for($i=0; $i<count($polygons); $i++) { 

     if($polygons[$i]!="") { 

      $res .= "<area shape=\"poly\" coords=\""; 

      $coordinates = explode("C", $polygons[$i]); 

      foreach($coordinates as $position) { 

       $noise = explode(" ", trim($position)); 
       $point = explode(",", $noise[0]); 

       for($j=0; $j<2; $j++) { 

        $val = round($point[$j]*$factor, 0); 

        if($j==0) 
         $res .= ($val + $x).","; 
        else 
         $res .= ($val + $y).","; 
       } 
      } 
      $res .= "\" href=\"link.html\" alt=\"desc\" />"; 
     } 
    } 

    return $res = str_replace(",\"","\"", $res);; 
} 
?> 


<?php 

$svg = "M 6247.5037,5935.0511 C 6246.0707,5940.7838 6247.5037,5947.9495 C 6243.2043,5959.4149 z"; 

highlight_string(svg2imap($svg, $factor=0.33, $x=0, $y=0)); 

?> 
+1

Điều đó không hoàn toàn phù hợp với svg của inkscape. như là tất cả. và nó chứa đầy mã xấu. không đăng bài đó, trang web này có nghĩa là để giúp mọi người. –

0

Dường như chức năng "Gerhard Dinhof" không chính xác và tôi đang lãng phí thời gian cho việc đó. Ở đây bạn có thể tìm thấy một phiên bản sửa đổi được viết bằng C# để chuyển đổi một tệp SVG đơn giản thành các mã bản đồ html có liên quan. Cách sử dụng: MessageBox.Show (Svg2map ("c: \ test.svg"))

// Sample file contents: 
    // <?xml version="1.0" encoding="UTF-8" ?> 
    // <!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"> 
    // <svg width="739pt" height="692pt" viewBox="0 0 739 692" version="1.1" xmlns="http://www.w3.org/2000/svg"> 
    // <path fill="#fefefe" d=" M 0.00 0.00 L 190.18 0.00 C 188.15 2.70 186.03 5.53 185.30 8.90 L 0.00 0.00 Z" /> 
    // </svg> 
    private string Svg2map(string svg_file_path) 
    { 
     string[] svgLines = File.ReadAllLines(svg_file_path); 
     string svg = string.Join("", svgLines).ToLower(); 

     int temp; 
     int w = int.Parse(ExtractData(svg,0,out temp, "<svg", "width").Replace("pt", "").Replace("px", "")); 
     int h = int.Parse(ExtractData(svg, 0, out temp, "<svg", "height").Replace("pt", "").Replace("px", "")); 

     StringBuilder stringToFile = new StringBuilder(); 
     stringToFile.AppendLine(string.Format("<img id=\"image1\" src=\"image1.jpg\" border=\"0\" width=\"{0}\" height=\"{1}\" orgwidth=\"{0}\" orgheight=\"{1}\" usemap=\"#map1\" alt=\"\" />", w, h)); 
     stringToFile.AppendLine("<map name=\"map1\" id=\"map1\">"); 

     byte dataKey1 = (byte)'a'; 
     byte dataKey2 = (byte)'a'; 

     int startIndex = 0; 
     int endIndex = 0; 
     while (true) 
     { 
      string color = ExtractData(svg, startIndex, out endIndex, "<path", "fill"); 
      string svg_input = ExtractData(svg, startIndex, out endIndex, "<path", "d="); 
      if (svg_input == null) 
       break; 

      startIndex = endIndex; 

      /// Start.. 
      stringToFile.Append(string.Format("<area data-key=\"{0}{1}\" shape=\"poly\" href=\"targetpage.html\" alt=\"Description\" coords=\"", (char)dataKey1, (char)dataKey2)); 
      dataKey1 += 1; 
      if (dataKey1 > (byte)'z') 
      { 
       dataKey2 += 1; 
       dataKey1 = (byte)'a'; 
      } 

      bool bFinished = false; 
      while (!bFinished) 
      { 
       string[] points = new string[0]; 
       string pattern = ""; 
       svg_input = svg_input.ToUpper().Trim(); 
       char code = svg_input[0]; 
       switch (code) 
       { 
        case 'M': 
        case 'L': 
         pattern = svg_input.Substring(0, svg_input.IndexOf(" ", svg_input.IndexOf(" ", svg_input.IndexOf(" ") + 1) + 1)); 
         svg_input = svg_input.Remove(0, pattern.Length); 
         points = pattern.Trim().Substring(1).Trim().Split(' '); 
         break; 
        case 'C': 
         pattern = svg_input.Substring(0, svg_input.IndexOf(" ", svg_input.IndexOf(" ", svg_input.IndexOf(" ", svg_input.IndexOf(" ", svg_input.IndexOf(" ", svg_input.IndexOf(" ", svg_input.IndexOf(" ") + 1) + 1) + 1) + 1) + 1) + 1)); 
         svg_input = svg_input.Remove(0, pattern.Length); 
         points = pattern.Trim().Substring(1).Trim().Split(' '); 
         break; 
        case 'Z': 
         bFinished = true; 
         continue; 
        default: 
         throw new Exception("Invalid pattern"); 
       } 

       int count = points.Length; 
       if (count > 4) 
        count = 4; 
       for (int i = 0; i < count; i++) 
       { 
        var valueParts = points[i].Split('.'); 
        // remove part after comma - we don't need this accurancy in HTML 
        stringToFile.Append(valueParts[0]); 
        // comma for seperation - don't worry, we'll clean the last ones within an area out later 
        stringToFile.Append(","); 
       } 
      } 
      stringToFile.AppendLine("\" />"); 
     } 

     // clean obsolete commas - not pretty nor efficient 
     stringToFile.AppendLine("</map>"); 
     stringToFile = stringToFile.Replace(",\"", "\""); 


     return stringToFile.ToString(); 
    } 

    private string ExtractData(string data, int startIndex, out int endIndex, string key, string param) 
    { 
     try 
     { 
      endIndex = 0; 
      int a = data.IndexOf(key, startIndex); 
      int a2 = data.IndexOf(key, a + key.Length); 
      if (a2 == -1) 
       a2 = data.IndexOf(">", a + key.Length); 
      int b = data.IndexOf(param, a + key.Length); 
      int start = data.IndexOf("\"", b + param.Length) + 1; 
      int end = data.IndexOf("\"", start + 1); 
      if (b > a2 || start > a2 || end > a2) 
       return null; 
      int len = end - start; 
      endIndex = end; 
      string t = data.Substring(start, len); 
      return t; 
     } 
     catch 
     { 
      endIndex = 0; 
      return null; 
     } 
    } 
Các vấn đề liên quan