コード例 #1
0
ファイル: quakes.go プロジェクト: GeoNet/haz
func getQuakesWfs(r *http.Request, h http.Header, b *bytes.Buffer) *weft.Result {
	//1. check query parameters
	if res := weft.CheckQuery(r, requiredParams, optionalParams); !res.Ok {
		return res
	}
	v := r.URL.Query()
	params, err := getQueryParams(v)
	if err != nil {
		return weft.BadRequest(err.Error())
	}

	if params.outputFormat == "JSON" {
		return getQuakesGeoJson(r, h, b, params)
	} else if params.outputFormat == "CSV" {
		return getQuakesCsv(r, h, b, params)
	} else if params.outputFormat == "GML2" {
		return getQuakesGml2(r, h, b, params)
		//text/xml; subtype=gml/3.2
	} else if params.outputFormat == "TEXT/XML" && params.subType == "GML/3.2" {
		return getQuakesGml3(r, h, b, params)
	} else {
		return weft.BadRequest("Invalid outputFormat")
	}
	return &weft.StatusOK
}
コード例 #2
0
ファイル: quakeWWW.go プロジェクト: GeoNet/haz
func quakesWWWnz(r *http.Request, h http.Header, b *bytes.Buffer) *weft.Result {
	if res := weft.CheckQuery(r, []string{}, []string{}); !res.Ok {
		return res
	}

	path := r.URL.Path[quakesNZServiceLen:] // ..."3/100.json"
	tokens := strings.Split(path, "/")
	if len(tokens) != 2 {
		return weft.BadRequest("Bad URL path.")
	}

	var mmi int
	var err error
	var count int
	if mmi, err = strconv.Atoi(tokens[0]); err != nil {
		return weft.BadRequest("Bad URL path. Invalid mmi.")
	}

	if count, err = strconv.Atoi(tokens[1][:len(tokens[1])-5]); err != nil { // len(".json")
		return weft.BadRequest("Bad URL path. Invalid count.")
	}

	var d string
	err = db.QueryRow(quakesNZWWWSQL, mmi, count).Scan(&d)
	if err != nil {
		return weft.ServiceUnavailableError(err)
	}

	b.WriteString(d)
	h.Set("Content-Type", JSON)
	return &weft.StatusOK
}
コード例 #3
0
ファイル: search.go プロジェクト: GeoNet/mtr
func searchPageHandler(r *http.Request, h http.Header, b *bytes.Buffer) *weft.Result {

	var err error
	var p *searchPage

	if res := weft.CheckQuery(r, []string{"tagQuery"}, []string{"page"}); !res.Ok {
		return res
	}
	r.ParseForm()
	tagQuery := r.FormValue("tagQuery")

	// Javascript should handle empty query value
	// Non existent value comes from unauthorized submit
	if tagQuery == "" {
		return weft.BadRequest("missing required query parameter: tagQuery")
	}

	if p, err = newSearchPage(mtrApiUrl); err != nil {
		return weft.BadRequest("error creating searchPage object")
	}

	if err = p.populateTags(); err != nil {
		return weft.InternalServerError(err)
	}

	if err = p.matchingMetrics(tagQuery); err != nil {
		return weft.InternalServerError(err)
	}

	if err := tagSearchTemplate.ExecuteTemplate(b, "border", p); err != nil {
		return weft.InternalServerError(err)
	}

	return &weft.StatusOK
}
コード例 #4
0
ファイル: data_latency_threshold.go プロジェクト: GeoNet/mtr
func dataLatencyThresholdPut(r *http.Request, h http.Header, b *bytes.Buffer) *weft.Result {
	v := r.URL.Query()
	var err error

	var lower, upper int

	if lower, err = strconv.Atoi(v.Get("lower")); err != nil {
		return weft.BadRequest("invalid lower")
	}

	if upper, err = strconv.Atoi(v.Get("upper")); err != nil {
		return weft.BadRequest("invalid upper")
	}

	siteID := v.Get("siteID")
	typeID := v.Get("typeID")

	var result sql.Result

	// TODO Change to upsert 9.5

	// return if insert succeeds
	if result, err = db.Exec(`INSERT INTO data.latency_threshold(sitePK, typePK, lower, upper)
				SELECT sitePK, typePK, $3, $4
				FROM data.site, data.type
				WHERE siteID = $1
				AND typeID = $2`,
		siteID, typeID, lower, upper); err == nil {
		var i int64
		if i, err = result.RowsAffected(); err != nil {
			return weft.InternalServerError(err)
		}
		if i == 1 {
			return &weft.StatusOK
		}
	}

	// return if update one row
	if pqErr, ok := err.(*pq.Error); ok && pqErr.Code == errorUniqueViolation {
		if result, err = db.Exec(`UPDATE data.latency_threshold SET lower=$3, upper=$4
				WHERE sitePK = (SELECT sitePK FROM data.site WHERE siteID = $1)
				AND typePK = (SELECT typePK FROM data.type WHERE typeID = $2)`,
			siteID, typeID, lower, upper); err == nil {
			var i int64
			if i, err = result.RowsAffected(); err != nil {
				return weft.InternalServerError(err)
			}
			if i == 1 {
				return &weft.StatusOK
			}
		}
	}

	if err == nil {
		err = fmt.Errorf("no rows affected, check your query.")
	}

	return weft.InternalServerError(err)
}
コード例 #5
0
ファイル: field_device.go プロジェクト: GeoNet/mtr
func fieldDevicePut(r *http.Request, h http.Header, b *bytes.Buffer) *weft.Result {
	v := r.URL.Query()

	var err error
	var latitude, longitude float64

	if latitude, err = strconv.ParseFloat(v.Get("latitude"), 64); err != nil {
		return weft.BadRequest("latitude invalid")
	}

	if longitude, err = strconv.ParseFloat(v.Get("longitude"), 64); err != nil {
		return weft.BadRequest("longitude invalid")
	}

	var result sql.Result

	// TODO - use upsert with PG 9.5?

	// return if insert succeeds
	if result, err = db.Exec(`INSERT INTO field.device(deviceID, modelPK, latitude, longitude)
				SELECT $1, modelPK, $3, $4
				FROM field.model
				WHERE modelID = $2`,
		v.Get("deviceID"), v.Get("modelID"), latitude, longitude); err == nil {
		var i int64
		if i, err = result.RowsAffected(); err != nil {
			return weft.InternalServerError(err)
		}
		if i == 1 {
			return &weft.StatusOK
		}
	}

	// return if update one row
	if pqErr, ok := err.(*pq.Error); ok && pqErr.Code == errorUniqueViolation {
		if result, err = db.Exec(`UPDATE field.device
					SET latitude = $2, longitude = $3
					WHERE deviceID = $1`,
			v.Get("deviceID"), latitude, longitude); err == nil {
			var i int64
			if i, err = result.RowsAffected(); err != nil {
				return weft.InternalServerError(err)
			}
			if i == 1 {
				return &weft.StatusOK
			}
		}
	}

	if err == nil {
		err = fmt.Errorf("no rows affected, check your query.")
	}

	return weft.InternalServerError(err)
}
コード例 #6
0
ファイル: quake.go プロジェクト: GeoNet/haz
func quakesRegionV1(r *http.Request, h http.Header, b *bytes.Buffer) *weft.Result {
	if res := weft.CheckQuery(r, []string{"regionID", "regionIntensity", "number", "quality"}, []string{}); !res.Ok {
		return res
	}

	var err error
	if _, err = getRegionID(r); err != nil {
		return weft.BadRequest(err.Error())
	}

	if _, err = getQuality(r); err != nil {
		return weft.BadRequest(err.Error())
	}

	var regionIntensity string

	if regionIntensity, err = getRegionIntensity(r); err != nil {
		return weft.BadRequest(err.Error())
	}

	var n int
	if n, err = getNumberQuakes(r); err != nil {
		return weft.BadRequest(err.Error())
	}

	var d string
	err = db.QueryRow(
		`SELECT row_to_json(fc)
                         FROM ( SELECT 'FeatureCollection' as type, COALESCE(array_to_json(array_agg(f)), '[]') as features
                         FROM (SELECT 'Feature' as type,
                         ST_AsGeoJSON(q.geom)::json as geometry,
                         row_to_json((SELECT l FROM
                         	(
                         		SELECT
                         		publicid AS "publicID",
                                to_char(time, 'YYYY-MM-DD"T"HH24:MI:SS.MS"Z"') as "time",
                                depth,
                                magnitude,
                                locality,
                                intensity,
                                intensity_newzealand as "regionIntensity",
                                quality
                           ) as l
                         )) as properties FROM haz.quakeapi as q where mmid_newzealand >= $1
                         ORDER BY time DESC  limit $2 ) as f ) as fc`, int(msg.IntensityMMI(regionIntensity)), n).Scan(&d)
	if err != nil {
		return weft.ServiceUnavailableError(err)
	}

	b.WriteString(d)
	h.Set("Content-Type", V1GeoJSON)
	return &weft.StatusOK
}
コード例 #7
0
ファイル: data_site.go プロジェクト: GeoNet/mtr
func dataSitePut(r *http.Request, h http.Header, b *bytes.Buffer) *weft.Result {
	v := r.URL.Query()

	siteID := v.Get("siteID")

	var err error
	var latitude, longitude float64

	if latitude, err = strconv.ParseFloat(v.Get("latitude"), 64); err != nil {
		return weft.BadRequest("latitude invalid")
	}

	if longitude, err = strconv.ParseFloat(v.Get("longitude"), 64); err != nil {
		return weft.BadRequest("longitude invalid")
	}

	var result sql.Result

	// TODO - use upsert with PG 9.5?

	// return if insert succeeds
	if result, err = db.Exec(`INSERT INTO data.site(siteID, latitude, longitude) VALUES($1, $2, $3)`,
		siteID, latitude, longitude); err == nil {
		var i int64
		if i, err = result.RowsAffected(); err != nil {
			return weft.InternalServerError(err)
		}
		if i == 1 {
			return &weft.StatusOK
		}
	}

	// return if update one row
	if pqErr, ok := err.(*pq.Error); ok && pqErr.Code == errorUniqueViolation {
		if result, err = db.Exec(`UPDATE data.site SET latitude=$2, longitude=$3 where siteID=$1`,
			siteID, latitude, longitude); err == nil {
			var i int64
			if i, err = result.RowsAffected(); err != nil {
				return weft.InternalServerError(err)
			}
			if i == 1 {
				return &weft.StatusOK
			}
		}
	}

	if err == nil {
		err = fmt.Errorf("no rows affected, check your query.")
	}

	return weft.InternalServerError(err)
}
コード例 #8
0
ファイル: field_state.go プロジェクト: GeoNet/mtr
func fieldStatePut(r *http.Request, h http.Header, b *bytes.Buffer) *weft.Result {
	q := r.URL.Query()
	deviceID := q.Get("deviceID")
	typeID := q.Get("typeID")

	var err error
	var value bool
	if value, err = strconv.ParseBool(q.Get("value")); err != nil {
		return weft.BadRequest("invalid value")
	}

	var t time.Time
	if t, err = time.Parse(time.RFC3339, q.Get("time")); err != nil {
		return weft.BadRequest("invalid time")
	}

	var result sql.Result
	if result, err = db.Exec(`UPDATE field.state SET
				time = $3, value = $4
				WHERE devicePK = (SELECT devicePK from field.device WHERE deviceID = $1)
				AND typePK = (SELECT typePK from field.state_type WHERE typeID = $2)`,
		deviceID, typeID, t, value); err != nil {
		return weft.InternalServerError(err)
	}

	// If no rows change either the values are old or it's the first time we've seen this metric.
	var u int64
	if u, err = result.RowsAffected(); err != nil {
		return weft.InternalServerError(err)
	}

	if u == 1 {
		return &weft.StatusOK
	} else if result, err = db.Exec(`INSERT INTO field.state(devicePK, typePK, time, value)
					SELECT devicePK, typePK, $3, $4
					FROM field.device, field.state_type
					WHERE deviceID = $1
					AND typeID = $2`,
		deviceID, typeID, t, value); err == nil {

		var i int64
		if i, err = result.RowsAffected(); err != nil {
			return weft.InternalServerError(err)
		}
		if i == 1 {
			return &weft.StatusOK
		}
	}

	return weft.InternalServerError(err)
}
コード例 #9
0
ファイル: intensity.go プロジェクト: GeoNet/haz
func intensityMeasuredLatestV1(r *http.Request, h http.Header, b *bytes.Buffer) *weft.Result {
	if res := weft.CheckQuery(r, []string{"type"}, []string{}); !res.Ok {
		return res
	}

	if r.URL.Query().Get("type") != "measured" {
		return weft.BadRequest("type must be measured.")
	}

	var d string

	err := db.QueryRow(
		`SELECT row_to_json(fc)
				FROM ( SELECT 'FeatureCollection' as type, COALESCE(array_to_json(array_agg(f)), '[]') as features
					FROM (SELECT 'Feature' as type,
						ST_AsGeoJSON(s.location)::json as geometry,
						row_to_json(( select l from 
							( 
								select mmi
								) as l )) 
			as properties from (select location, mmi 
				FROM impact.intensity_measured) as s 
			) As f )  as fc`).Scan(&d)
	if err != nil {
		return weft.ServiceUnavailableError(err)
	}

	b.WriteString(d)
	h.Set("Content-Type", V1GeoJSON)
	return &weft.StatusOK
}
コード例 #10
0
ファイル: field_metric_tag.go プロジェクト: GeoNet/mtr
func fieldMetricTagPut(r *http.Request, h http.Header, b *bytes.Buffer) *weft.Result {
	v := r.URL.Query()

	var err error
	var result sql.Result

	if result, err = db.Exec(`INSERT INTO field.metric_tag(devicePK, typePK, tagPK)
				SELECT devicePK, typePK, tagPK
				FROM field.device, field.type, mtr.tag
				WHERE deviceID = $1
				AND typeID = $2
				AND tag = $3`,
		v.Get("deviceID"), v.Get("typeID"), v.Get("tag")); err != nil {
		if err, ok := err.(*pq.Error); ok && err.Code == errorUniqueViolation {
			// ignore unique constraint errors
			return &weft.StatusOK
		} else {
			return weft.InternalServerError(err)
		}
	}

	var i int64
	if i, err = result.RowsAffected(); err != nil {
		return weft.InternalServerError(err)
	}
	if i != 1 {
		return weft.BadRequest("Didn't create row, check your query parameters exist")
	}

	return &weft.StatusOK
}
コード例 #11
0
ファイル: volcanoV2.go プロジェクト: GeoNet/haz
func volcanoRegionV2(r *http.Request, h http.Header, b *bytes.Buffer) *weft.Result {

	if res := weft.CheckQuery(r, []string{}, []string{}); !res.Ok {
		return res
	}

	var err error
	var volcanoId string

	if volcanoId, err = getVolcanoIDRegion(r); err != nil {
		return weft.BadRequest(err.Error())
	}

	var d string
	err = db.QueryRow(`SELECT row_to_json(fc)
			FROM ( SELECT 'FeatureCollection' as type, COALESCE(array_to_json(array_agg(f)), '[]') as features
			FROM (SELECT 'Feature' as type,
			ST_AsGeoJSON(r.region)::json as geometry,
			row_to_json((SELECT l FROM
			(
			SELECT	id,
			title
			) as l
			)) as properties
			FROM haz.volcano as r
			where id = $1) as f ) as fc;`, volcanoId).Scan(&d)
	if err != nil {
		return weft.ServiceUnavailableError(err)
	}

	b.WriteString(d)
	h.Set("Content-Type", V2GeoJSON)
	return &weft.StatusOK
}
コード例 #12
0
ファイル: quakeV2.go プロジェクト: GeoNet/haz
func quakeV2(r *http.Request, h http.Header, b *bytes.Buffer) *weft.Result {
	if res := weft.CheckQuery(r, []string{}, []string{}); !res.Ok {
		return res
	}

	if len(r.URL.Query()) != 0 {
		return weft.BadRequest("incorrect number of query parameters.")
	}

	var publicID string
	var res *weft.Result

	if publicID, res = getPublicIDPath(r); !res.Ok {
		return res
	}

	var d string
	err := db.QueryRow(quakeV2SQL, publicID).Scan(&d)
	if err != nil {
		return weft.ServiceUnavailableError(err)
	}

	b.WriteString(d)
	h.Set("Content-Type", V2GeoJSON)
	return &weft.StatusOK
}
コード例 #13
0
ファイル: tag_page.go プロジェクト: GeoNet/mtr
func tagPageHandler(r *http.Request, h http.Header, b *bytes.Buffer) *weft.Result {
	var err error

	if res := weft.CheckQuery(r, []string{}, []string{}); !res.Ok {
		return res
	}

	p := tagPage{}
	p.Path = r.URL.Path
	p.Border.Title = "GeoNet MTR"
	p.ActiveTab = "Tag"

	if err = p.populateTags(); err != nil {
		return weft.InternalServerError(err)
	}

	ph := strings.TrimPrefix(p.Path, "/tag")
	if strings.HasPrefix(ph, "/") {
		ph = ph[1:]
	}

	currTab := -1

	// Create grouping tabs
	p.TagTabs = make([]string, 0)
	for i, k := range tagGrouper {
		s := k[:1] + "-" + k[len(k)-1:]
		p.TagTabs = append(p.TagTabs, s)
		if ph == s {
			currTab = i
		}
	}

	if currTab == -1 && ph != "" {
		return weft.BadRequest("Invalid tag index.")
	}

	if ph == "" {
		currTab = 0
	}

	p.Path = p.TagTabs[currTab]

	for _, t := range p.Border.TagList {
		c := t[:1]
		if strings.Contains(tagGrouper[currTab], c) {
			p.Tags = append(p.Tags, t)
		}
	}

	if err = tagPageTemplate.ExecuteTemplate(b, "border", p); err != nil {
		return weft.InternalServerError(err)
	}
	return &weft.StatusOK
}
コード例 #14
0
ファイル: server_test.go プロジェクト: GeoNet/mtr
func delApplication(applicationID string) *weft.Result {
	if applicationID == "" {
		return weft.BadRequest("empty applicationID")
	}

	if _, err := db.Exec(`DELETE FROM app.application WHERE applicationID = $1`, applicationID); err != nil {
		return weft.InternalServerError(err)
	}

	return &weft.StatusOK
}
コード例 #15
0
ファイル: docs.go プロジェクト: GeoNet/haz
func docs(r *http.Request, h http.Header, b *bytes.Buffer) *weft.Result {
	if res := weft.CheckQuery(r, []string{}, []string{}); !res.Ok {
		return res
	}

	if r.URL.Path != "/" {
		return weft.BadRequest("invalid path")
	}

	b.Write(docsIndex)
	return &weft.StatusOK
}
コード例 #16
0
ファイル: quakes.go プロジェクト: GeoNet/haz
func getQuakesCsv(r *http.Request, h http.Header, b *bytes.Buffer) *weft.Result {
	//1. check query parameters
	if res := weft.CheckQuery(r, []string{}, optionalParams); !res.Ok {
		return res
	}

	v := r.URL.Query()
	//21  fields
	sqlString := `select format('%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s',
               publicid,eventtype,to_char(origintime, 'YYYY-MM-DD"T"HH24:MI:SS.MS"Z"'),
               to_char(modificationtime, 'YYYY-MM-DD"T"HH24:MI:SS.MS"Z"'),longitude, latitude, magnitude,
               depth,magnitudetype, depthtype, evaluationmethod, evaluationstatus, evaluationmode, earthmodel, usedphasecount,
               usedstationcount,magnitudestationcount, minimumdistance,
               azimuthalgap,originerror,magnitudeuncertainty) as csv from haz.quake_search_v1`

	params, err := getQueryParams(v)
	if err != nil {
		return weft.BadRequest(err.Error())
	}

	sqlString, args := getSqlQuery(sqlString, params)

	rows, err := db.Query(sqlString, args...)

	if err != nil {
		return weft.InternalServerError(err)
	}
	defer rows.Close()

	var (
		// b bytes.Buffer
		d string
	)

	b.WriteString("publicid,eventtype,origintime,modificationtime,longitude, latitude, magnitude, depth,magnitudetype,depthtype," +
		"evaluationmethod,evaluationstatus,evaluationmode,earthmodel,usedphasecount,usedstationcount,magnitudestationcount,minimumdistance," +
		"azimuthalgap,originerror,magnitudeuncertainty")
	b.WriteString("\n")
	for rows.Next() {
		err := rows.Scan(&d)
		if err != nil {
			return weft.InternalServerError(err)
		}
		b.WriteString(d)
		b.WriteString("\n")
	}

	// send result response
	h.Set("Content-Disposition", `attachment; filename="earthquakes.csv"`)
	h.Set("Content-Type", CONTENT_TYPE_CSV)
	return &weft.StatusOK
}
コード例 #17
0
ファイル: field_metric_tag.go プロジェクト: GeoNet/mtr
func fieldMetricTagProto(r *http.Request, h http.Header, b *bytes.Buffer) *weft.Result {
	var err error
	var rows *sql.Rows

	deviceID := r.URL.Query().Get("deviceID")
	typeID := r.URL.Query().Get("typeID")

	if deviceID == "" && typeID == "" {
		if rows, err = dbR.Query(`SELECT deviceID, tag, typeID from field.metric_tag
				JOIN mtr.tag USING (tagpk)
				JOIN field.device USING (devicepk)
				JOIN field.type USING (typepk)
				ORDER BY tag ASC`); err != nil {
			return weft.InternalServerError(err)
		}
		defer rows.Close()
	} else if deviceID != "" && typeID != "" {
		if rows, err = dbR.Query(`SELECT deviceID, tag, typeID from field.metric_tag
				JOIN mtr.tag USING (tagpk)
				JOIN field.device USING (devicepk)
				JOIN field.type USING (typepk)
				WHERE deviceID=$1 AND typeID=$2
				ORDER BY tag ASC`, deviceID, typeID); err != nil {
			return weft.InternalServerError(err)
		}
		defer rows.Close()

	} else {
		return weft.BadRequest("Invalid parameter. Please specify both deviceID and typeID.")
	}

	var ts mtrpb.FieldMetricTagResult

	for rows.Next() {
		var t mtrpb.FieldMetricTag

		if err = rows.Scan(&t.DeviceID, &t.Tag, &t.TypeID); err != nil {
			return weft.InternalServerError(err)
		}

		ts.Result = append(ts.Result, &t)
	}

	var by []byte
	if by, err = proto.Marshal(&ts); err != nil {
		return weft.InternalServerError(err)
	}

	b.Write(by)

	return &weft.StatusOK
}
コード例 #18
0
ファイル: intensityProto.go プロジェクト: junghao/haz
func intensityProto(r *http.Request, h http.Header, b *bytes.Buffer) *weft.Result {
	if res := weft.CheckQuery(r, []string{"type"}, []string{"publicID"}); !res.Ok {
		return res
	}

	var ts string
	var err error

	if ts, err = getIntensityType(r); err != nil {
		return weft.BadRequest(err.Error())
	}

	var shaking *haz.Shaking

	switch ts {
	case "measured":
		if shaking, err = intensityMeasuredLatest(); err != nil {
			return weft.ServiceUnavailableError(err)
		}
	case "reported":
		publicID := r.URL.Query().Get("publicID")
		switch publicID {
		case "":
			end := time.Now().UTC()
			start := end.Add(-60 * time.Minute)
			if shaking, err = intensityReported(start, end); err != nil {
				return weft.ServiceUnavailableError(err)
			}
		default:
			var t time.Time
			var res *weft.Result
			if t, res = getQuakeTime(r); !res.Ok {
				return res
			}
			start := t.Add(-1 * time.Minute)
			end := t.Add(15 * time.Minute)
			if shaking, err = intensityReported(start, end); err != nil {
				return weft.ServiceUnavailableError(err)
			}
		}
	}

	var by []byte
	if by, err = proto.Marshal(shaking); err != nil {
		return weft.ServiceUnavailableError(err)
	}

	b.Write(by)
	h.Set("Content-Type", protobuf)

	return &weft.StatusOK
}
コード例 #19
0
ファイル: tag.go プロジェクト: GeoNet/mtr
func tagDelete(r *http.Request, h http.Header, b *bytes.Buffer) *weft.Result {
	tag := strings.TrimPrefix(r.URL.Path, "/tag/")

	if tag == "" {
		return weft.BadRequest("empty tag")
	}

	if _, err := db.Exec(`DELETE FROM mtr.tag WHERE tag=$1`, tag); err != nil {
		return weft.InternalServerError(err)
	}

	return &weft.StatusOK
}
コード例 #20
0
ファイル: volcanoProto.go プロジェクト: GeoNet/haz
func volcanoRegionHistoryProto(r *http.Request, h http.Header, b *bytes.Buffer) *weft.Result {
	if res := weft.CheckQuery(r, []string{}, []string{}); !res.Ok {
		return res
	}

	var volcanoId string
	var err error

	if volcanoId, err = getVolcanoRegionHistory(r); err != nil {
		return weft.BadRequest(err.Error())
	}

	var rows *sql.Rows

	if rows, err = db.Query(fmt.Sprintf(volcanoRegionHistoryProtoSQL, 90), volcanoId); err != nil {
		return weft.ServiceUnavailableError(err)
	}

	var quakes []*haz.Quake

	for rows.Next() {
		var t time.Time
		var mt time.Time
		q := haz.Quake{}

		if err = rows.Scan(&q.PublicID, &t, &mt, &q.Depth,
			&q.Magnitude, &q.Locality, &q.Mmi, &q.Quality,
			&q.Longitude, &q.Latitude); err != nil {
			return weft.ServiceUnavailableError(err)
		}

		q.Time = &haz.Timestamp{Sec: t.Unix(), Nsec: int64(t.Nanosecond())}
		q.ModificationTime = &haz.Timestamp{Sec: mt.Unix(), Nsec: int64(mt.Nanosecond())}

		quakes = append(quakes, &q)
	}

	qs := haz.Quakes{Quakes: quakes}

	var by []byte

	if by, err = proto.Marshal(&qs); err != nil {
		return weft.ServiceUnavailableError(err)
	}

	b.Write(by)
	h.Set("Content-Type", protobuf)
	return &weft.StatusOK
}
コード例 #21
0
ファイル: router.go プロジェクト: GeoNet/haz
func indexPage(r *http.Request, h http.Header, b *bytes.Buffer) *weft.Result {
	if res := weft.CheckQuery(r, []string{}, []string{}); !res.Ok {
		return res
	}
	if r.URL.Path != "/" {
		return weft.BadRequest("invalid path")
	}

	err := indexTemp.Execute(b, nil)

	if err != nil {
		return weft.InternalServerError(err)
	}

	return &weft.StatusOK
}
コード例 #22
0
ファイル: tag.go プロジェクト: GeoNet/mtr
func tagPut(r *http.Request, h http.Header, b *bytes.Buffer) *weft.Result {
	tag := strings.TrimPrefix(r.URL.Path, "/tag/")

	if tag == "" {
		return weft.BadRequest("empty tag")
	}

	if _, err := db.Exec(`INSERT INTO mtr.tag(tag) VALUES($1)`, tag); err != nil {
		if err, ok := err.(*pq.Error); ok && err.Code == errorUniqueViolation {
			//	no-op.  Nothing to update.
		} else {
			return weft.InternalServerError(err)
		}
	}

	return &weft.StatusOK
}
コード例 #23
0
ファイル: quakes.go プロジェクト: GeoNet/haz
func getQuakesCsv(r *http.Request, h http.Header, b *bytes.Buffer, params *QueryParams) *weft.Result {
	//21  fields
	sqlPre := `select format('%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s',
               publicid,eventtype,to_char(origintime, 'YYYY-MM-DD"T"HH24:MI:SS.MS"Z"'),
               to_char(modificationtime, 'YYYY-MM-DD"T"HH24:MI:SS.MS"Z"'),CAST(longitude AS NUMERIC(16,8)),
               CAST(latitude AS NUMERIC(16,8)), CAST(magnitude AS NUMERIC(16,8)), CAST(depth AS NUMERIC(16,8)),
               magnitudetype, depthtype, evaluationmethod, evaluationstatus, evaluationmode, earthmodel, usedphasecount,
               usedstationcount,magnitudestationcount, CAST(minimumdistance AS NUMERIC(16,8)),CAST(azimuthalgap AS NUMERIC(16,8)),
               CAST(originerror AS NUMERIC(16,8)),CAST(magnitudeuncertainty AS NUMERIC(16,8)) ) as csv
               from haz.quake_search_v1`

	sqlString, args, err1 := getSqlQueryString(sqlPre, params)
	if err1 != nil {
		return weft.BadRequest(err1.Error())
	}

	rows, err := db.Query(sqlString, args...)

	if err != nil {
		return weft.InternalServerError(err)
	}
	defer rows.Close()

	var (
		d string
	)

	b.WriteString("publicid,eventtype,origintime,modificationtime,longitude,latitude,magnitude,depth,magnitudetype,depthtype," +
		"evaluationmethod,evaluationstatus,evaluationmode,earthmodel,usedphasecount,usedstationcount,magnitudestationcount,minimumdistance," +
		"azimuthalgap,originerror,magnitudeuncertainty")
	b.WriteString("\n")
	for rows.Next() {
		err := rows.Scan(&d)
		if err != nil {
			return weft.InternalServerError(err)
		}
		b.WriteString(d)
		b.WriteString("\n")
	}

	// send result response
	h.Set("Content-Disposition", `attachment; filename="earthquakes.csv"`)
	h.Set("Content-Type", CONTENT_TYPE_CSV)
	return &weft.StatusOK
}
コード例 #24
0
ファイル: valid.go プロジェクト: GeoNet/haz
func getPublicIDPath(r *http.Request) (string, *weft.Result) {
	publicID := r.URL.Path[quakeLen:]

	if !publicIDRe.MatchString(publicID) {
		return publicID, weft.BadRequest("invalid publicID: " + publicID)
	}

	var d string
	err := db.QueryRow("select publicid FROM haz.quake where publicid = $1", publicID).Scan(&d)
	if err == sql.ErrNoRows {
		return publicID, &weft.NotFound
	}
	if err != nil {
		return publicID, weft.ServiceUnavailableError(err)
	}

	return publicID, &weft.StatusOK
}
コード例 #25
0
ファイル: valid.go プロジェクト: GeoNet/haz
func getQuakeTime(r *http.Request) (time.Time, *weft.Result) {
	publicID := r.URL.Query().Get("publicID")
	originTime := time.Time{}

	if !publicIDRe.MatchString(publicID) {
		return originTime, weft.BadRequest(fmt.Sprintf("invalid publicID " + publicID))
	}

	err := db.QueryRow("select time FROM haz.quake where publicid = $1", publicID).Scan(&originTime)
	if err == sql.ErrNoRows {
		return originTime, &weft.NotFound
	}
	if err != nil {
		return originTime, weft.ServiceUnavailableError(err)
	}

	return originTime, &weft.StatusOK
}
コード例 #26
0
ファイル: quakes.go プロジェクト: GeoNet/haz
/**
 * get the number of quakes with breaking dates when the number is large
 */
func getQuakesCount(r *http.Request, h http.Header, b *bytes.Buffer) *weft.Result {

	//1. check query parameters
	if res := weft.CheckQuery(r, []string{}, optionalParams); !res.Ok {
		return res
	}

	v := r.URL.Query()
	sqlString := `select count(*) from haz.quake_search_v1`

	params, err := getQueryParams(v)
	if err != nil {
		return weft.BadRequest(err.Error())
	}

	sqlString, args := getSqlQuery(sqlString, params)
	var count int
	err = db.QueryRow(sqlString, args...).Scan(&count)
	if err != nil {
		return weft.InternalServerError(err)
	}

	resp := "{\"count\":" + strconv.Itoa(count)

	if count > MAX_QUAKES_NUMBER { //get break dates
		breakDates := getBreakDates(params)
		if len(breakDates) > 0 {
			resp += ", \n\"dates\":["
			for n, date := range breakDates {
				if n > 0 {
					resp += ","
				}
				resp += "\"" + date + "\""
			}
			resp += "]\n"
		}
	}
	resp += "}"

	h.Set("Content-Type", CONTENT_TYPE_JSON)
	b.WriteString(resp)
	return &weft.StatusOK

}
コード例 #27
0
ファイル: volcanoV2.go プロジェクト: GeoNet/haz
func quakesVolcanoRegionV2(r *http.Request, h http.Header, b *bytes.Buffer) *weft.Result {

	if res := weft.CheckQuery(r, []string{}, []string{}); !res.Ok {
		return res
	}

	var err error
	var days int = 90
	var volcanoId string

	if volcanoId, err = getVolcanoIDQuake(r); err != nil {
		return weft.BadRequest(err.Error())
	}

	var d string
	err = db.QueryRow(`SELECT row_to_json(fc)
			FROM ( SELECT 'FeatureCollection' as type, COALESCE(array_to_json(array_agg(f)), '[]') as features
			FROM (SELECT 'Feature' as type,
			ST_AsGeoJSON(q.geom)::json as geometry,
			row_to_json((SELECT l FROM
				(
				SELECT	publicid AS "publicID",
					to_char(time, 'YYYY-MM-DD"T"HH24:MI:SS.MS"Z"') as "time",
					depth,
					magnitude,
					locality,
					intensity,
					intensity_newzealand as "regionIntensity",
					floor(mmid_newzealand) as "mmi",
					quality
				) as l
			)) as properties
			FROM haz.quakeapi as q
			where st_covers((select region from haz.volcano hv where id = $1 and q.depth < hv.depth and DATE_PART('day', now() - q.time) < $2), q.geom)
			ORDER BY time DESC ) as f ) as fc;`, volcanoId, days).Scan(&d)
	if err != nil {
		return weft.ServiceUnavailableError(err)
	}

	b.WriteString(d)
	h.Set("Content-Type", V2GeoJSON)
	return &weft.StatusOK
}
コード例 #28
0
ファイル: router.go プロジェクト: GeoNet/haz
func indexPage(r *http.Request, h http.Header, b *bytes.Buffer) *weft.Result {
	if res := weft.CheckQuery(r, []string{}, []string{}); !res.Ok {
		return res
	}
	if r.URL.Path != "/" {
		return weft.BadRequest("invalid path")
	}

	var p searchPage
	p.ApiKey = os.Getenv("BING_API_KEY")

	err := indexTemp.ExecuteTemplate(b, "base", p)

	if err != nil {
		return weft.InternalServerError(err)
	}

	return &weft.StatusOK
}
コード例 #29
0
ファイル: quakeV2.go プロジェクト: GeoNet/haz
func quakeStatsV2(r *http.Request, h http.Header, b *bytes.Buffer) *weft.Result {
	if res := weft.CheckQuery(r, []string{}, []string{}); !res.Ok {
		return res
	}

	if len(r.URL.Query()) != 0 {
		return weft.BadRequest("incorrect number of query parameters.")
	}

	var d string
	err := db.QueryRow(quakeStatsV2SQL).Scan(&d)
	if err != nil {
		return weft.ServiceUnavailableError(err)
	}

	b.WriteString(d)
	h.Set("Surrogate-Control", maxAge300)
	h.Set("Content-Type", V2JSON)
	return &weft.StatusOK
}
コード例 #30
0
ファイル: quakeWWW.go プロジェクト: GeoNet/haz
func quakeWWW(r *http.Request, h http.Header, b *bytes.Buffer) *weft.Result {
	if res := weft.CheckQuery(r, []string{}, []string{}); !res.Ok {
		return res
	}

	publicID := strings.TrimSuffix(strings.TrimPrefix(r.URL.Path, "/quake/services/quake/"), ".json")
	if publicID == "" {
		return weft.BadRequest("invalid publicID path: " + r.URL.Path)
	}

	var d string
	err := db.QueryRow(quakeWWWSQL, publicID).Scan(&d)
	if err != nil {
		return weft.ServiceUnavailableError(err)
	}

	b.WriteString(d)
	h.Set("Content-Type", JSON)
	return &weft.StatusOK
}