原點科技介紹既2011年終回顧

原點科技成立於2010年十月,在過去的一年多間,本公司就為Location Based Service & Mobile開發及學習了許多技術。

Json WebService API with Jersey

身為SaaS的提供者,我們需要提供許多不同的WebService API給我們的客戶,在轉換內部的Java Object到外部的Json Object,我們選用的是Jersey這套 JAX-RS 標準的實作,以及Jackson這套 Json library。

這部份的成果,我們曾在2010年11月於 TWJUG 發表過,相關的投影片請見,另外關於Jackson的使用,我們也發表了幾篇部落格文章講解,怎麼在Scala上使用Jackson怎麼樣處理多型使用Jackson的小眉角,以及怎麼在Android上使用Jackson

對於 Jersey & Jackson 這一套 Json WebService framework,我們使用的經驗是很滿意,也大量的使用在我們的內外部系統間。

Search with Lucene

在 Lucene 之上,我們建立了一套,不同於Solr的 WebService 實作,透過我們自有的Search API,能夠對我們的Json文件庫做全文檢索及條件比對,並且可做翻頁、及選取部份欄位等運算。

Location Based(Spatial) Search

當我們開始做 LBS 時,一開始我們是始用 lucene-spatial 這套官方的函式庫來做 LBS ,但是,很快的,我們就了解到,用 Map Tile 來做 LBS 的問題,Map Tile的做法是,把地圖割成不同大小的區塊然後編號,然後,把這區塊內所有的座標,都標上一樣的 tag 值,例如 t16m2345 – t(tile_size)m(tile_id)。那麼,在做搜尋時,我們只要把現在的座標位址的tile id算出來,在去找有相同tile id的點就好。

這種做法的問題是,找出來的點,並沒有依距離排序;當 Lucene 對選出來的文件做 scoring 時,因為同一個區塊內的點都具有一樣的tile_id,所以,他們的分數都是一樣的,並不會依距離的不同,而有不同的分數。

另外,我們也發現,多數的搜尋技術,在處理地理位址時,只處理地點的資料,例如餐廳、百貨公司等小地理區塊等,但是這些地點搜詢技術,並不適合用在處理大區塊範圍的資料,如行政區及學區等。

如多數外國網站用的坐標轉行政區的GeoNames,他在搜尋某個座標目前所屬的行政區時,是計算座標點與附近行政區中心的距離來猜測,但是行政區往往不是正圓型的,行政區的劃分多是依自然環境(如河川)來切割的,所以,既始某個座標離行政區甲較近,但是,在實務上則是被劃分到乙行政區去的;類似的例子還有學區等

另一類無法用點去描述的,是線型的資料,如登山步道、腳踏車道,當我們登山時,我們不一定要從起點開始爬,而是可以從中間點開始加入,因此,當我們在找附近所有的登山步道時,該是計算所有線型資料與目前座標點的最短距離,而非是算起點與目前座標點的距離。

因此,就這兩個問題,我們實作了對地理區塊搜尋的功能,讓用戶能對點(Point)、線(LineString),多邊型(Polygon)等資料,做搜尋,並對尋結果依距離來排序。

就這功能,我們發表了搜詢座標所在行政區台北水災地圖

Search Analytics

講到搜尋,當然也不得不提用戶行為分析(Analytics),我們在我們的Search API中,內建了記錄使用者行為的功能,當一個使用者,打開程式送出第一個搜尋、翻到第二頁、點選了第三個連結、再做另一個搜尋、選了第一個結果、離開,這一整串的行為,都會被我們的後端自動記錄下來。

透過我們自己開發的 Mobile Analytics 技術,我們可以就這些使用者行為,提供底下的分析報告

  • Client Profiles
    • number of clients by device family
    • number of clients by device.
    • number of active clients by device family.
    • number of active clients by hour/day/week/month
    • the location of clients.
    • the location of active clients by hour/day/week/month.
    • average usage frequency(how often clients use your app per week)
  • Visit Trends
    • number of request of the hour/day/week/month
    • unique visits of the hour/day/week/month
    • average length of visits.
    • new vs return clients on the hour/day/week/month.
  • Search Usage
    • top search keywords of the hour/day/week/month.
    • top search keywords by location/country
    • the location of search usage of the hour/day/week
    • average search usage per visit.
    • top-exit search.
  • Content Usage:
    • popular contents.
    • popular result document ids.
    • top-exit result.

大量運算

在過去的一年多間,我們花了很多的心力在學習雲端相關技術,評估什麼技術適合我們,什麼不適合我們,像在做Analytics時,我們選用了MySQL而不是熱門的Hadoop

因為我們有群組軟體的需求,需要知道,在Cluster中,那幾台機器是負責處理 Domain X 的資料;我們嘗試了使用 jgroups 及 zookeper 來實作 service registry/discovery 的功能,這經驗,也在CloudTW發表過,投影片在此

為了在我們的 indexing 中使用 Producer and Consumer Pattern & durable message box,我們也投入了許多時間去學習Akka, Actor Model, Amazon SQS, ActiveMQ, Apache Camel,Akka的成果,我們也在 COSCUP 發表過Video on YouTube

社群服務

在我們專注於軟體開發的同時,原點科技也不忘回饋社會及社群,原點科技的創辦人加入多個社群,並多次主講議題,包括

  • TWJUG: Introduction to Tapestry
  • CloudTW: Groupware – JGroups and Zookeeper.
  • Coscup: Introduction to Actor Model and Akka
  • OpenData: 系列講座 #2 – 第一次爬資料就上手?! 碰壁!

在今年底,原點科技將協助Scala Taipei的運作

關於未來

在下一個年度,我們將會把心力放在推廣我們的產品Search Cloud之上,通過參展與競賽,增加我們的媒體知名度。另外一方面,我們也會開始接一些關於LBS, Analytics, Distributed System的外包案。

此外,我們也會把一部份的心力,放置在推廣 Scala 及 Akka 的企業應用,透過教育訓練、外包專案、雜誌文章及研討會的方式,讓台灣的軟體界對這兩者有更多的了解

New Feature: Support for Geometries.

A pair of latitude and longitude gives a quickstart for your location based application. However, not every single feature in a LBS application can be describe as a point. Let us take school district as an example. The School A may be closer to your house than School B is, but your house is belong to school district for school B. Another example is bike trails, bike trail is a line not a single point. This is why we introduce geometry support into SearchCloud.

In the GIS area, Geometry are used to describe shape of features. The geometry model in SearchCloud consists of single points, line strings, and polygons, multi-point, multi-line string, and multi-polygon collections, and geometry collections.

In the next section, we will walk through all the supported geometries and how to represent them.

Represent Geometry

There are few defeco standards for representing geometries.

  • WKT, well-known text, represents geometry in human readable text format
  • WKB, well-known text, represents geometry in machine readable binary format
  • GeoJSON represents geometry in json format.

In SearchCloud’s JSON API, we pick GeoJSON over WKT because it has better integration with other external services.

Supported Geometries

POINT consists of a coordinate pair in longitude, latitude order.

{ "type": "Point", "coordinates": [100.0, 0.0] }

LineString is made of an array of coordinate pairs.

{
  "type": "LineString",
  "coordinates": [ [100.0, 0.0], [101.0, 1.0] ]
}

Polygon is made of array of LineStrings. The first cicular linestring represent the exterior ring and the subsquent LineStrings represent the holes in the ring.

{
  "type": "Polygon",
  "coordinates": [
    [ [35, 10], [10, 20], [15, 40], [45, 45], [30, 10]]
  ]
}
{
  "type": "Polygon",
  "coordinates": [
    [ [35, 10], [10, 20], [15, 40], [45, 45], [30, 10]],
    [ [20, 30], [35, 35], [30, 20], [20, 30] ]
  ]
}

MultiPoint is made of an array of coordinate pairs.

{
  "type": "MultiPoint",
  "coordinates": [ [10, 40], [40, 30], [20, 20], [30, 10] ]
}

MultiLineString is made of an array of LineStrings.

{
  "type": "MultiLineString",
  "coordinates": [
    [ [10, 10], [20, 20], [30, 10] ],
    [ [40, 40], [30, 30], [40, 20], [30, 10] ]
  ]
}

MultiPolygon is made of an array of polygons.

{
  "type": "MultiPolygon",
  "coordinates": [
    [[[30 20], [10, 40], [35, 40], [30, 20]]],
    [[[15, 5], [40, 10], [10, 20], [ 5, 10], [15, 5]]]
  ]
}

GeometryCollection is made of an array of geometry objects described above.

{
  "type": "GeometryCollection",
  "geometries": [
    {
      "type": "Point",
      "coordinates": [100.0, 0.0]
    },
    {
      "type": "LineString",
      "coordinates": [ [100.0, 0.0], [101.0, 1.0] ]
    }
  ]
}

Define Geometry Field

A new GeometryFieldType is added to schema types.

{ "location"  : { "type": "geometry" }  }

Search for Geometry Field

The existing Location Query can be applied to geometry fields as well as location fields. The search results will be sorted by the distance between the requesting location and geometries described in the documents.