Tính khoản cách giữa 2 điểm bằng sql server và C#

sql server 

 --[dbo].[sp_DuAnGetKhoangCach] 10.7756587, 106.70042379999995, 0.5

CREATE PROCEDURE [dbo].[sp_DuAnGetKhoangCach]

    @ZipLatitude float, 
    @ZipLongitude float,
    @Radius  float
AS  
SELECT * FROM DuAn

WHERE dbo.TinhKhoanCach2Diem(lat, lng, @ZipLatitude, @ZipLongitude) < @Radius



CREATE FUNCTION TinhKhoanCach2Diem(
    @Latitude1 float,
    @Longitude1 float,
    @Latitude2 float,
    @Longitude2 float
)
RETURNS float 
AS  
    BEGIN 
    -- CONSTANTS
    DECLARE @EarthRadiusInMiles float;
    SET @EarthRadiusInMiles = 6371 -- 3959 for miles, 6371 for KM

    DECLARE @PI  float;
    SET @PI = PI();
    -- RADIANS conversion
    DECLARE @lat1Radians float;
    DECLARE @long1Radians float;
    DECLARE @lat2Radians float;
    DECLARE @long2Radians float;
    SET @lat1Radians = @Latitude1 * @PI / 180;
    SET @long1Radians = @Longitude1 * @PI / 180;
    SET @lat2Radians = @Latitude2 * @PI / 180;
    SET @long2Radians = @Longitude2 * @PI / 180;
    RETURN Acos(
    Cos(@lat1Radians) * Cos(@long1Radians) * Cos(@lat2Radians) * Cos(@long2Radians) + 
    Cos(@lat1Radians) * Sin(@long1Radians) * Cos(@lat2Radians) * Sin(@long2Radians) + 
    Sin(@lat1Radians) * Sin(@lat2Radians)
    ) * @EarthRadiusInMiles;
END

C#

/// <summary>
/// Specifies a Latitude / Longitude point.
/// </summary>
public class LatLng
{
    public double Latitude { get; set; }
    public double Longitude { get; set; }

    public LatLng(){
    }

    public LatLng(double lat, double lng)
    {
        this.Latitude = lat;
        this.Longitude = lng;
    }
}

/// <summary>
/// Returns the distance in miles or kilometers of any two
/// latitude / longitude points.
/// </summary>
/// <param name="pos1">Location 1</param>
/// <param name="pos2">Location 2</param>
/// <param name="unit">Miles or Kilometers</param>
/// <returns>Distance in the requested unit</returns>
public double HaversineDistance(LatLng pos1, LatLng pos2, DistanceUnit unit)
{
    double R = (unit == DistanceUnit.Miles) ? 3960 : 6371;
    var lat = (pos2.Latitude - pos1.Latitude).ToRadians();
    var lng = (pos2.Longitude - pos1.Longitude).ToRadians();
    var h1 = Math.Sin(lat / 2) * Math.Sin(lat / 2) +
                  Math.Cos(pos1.Latitude.ToRadians()) * Math.Cos(pos2.Latitude.ToRadians()) *
                  Math.Sin(lng / 2) * Math.Sin(lng / 2);
    var h2 = 2 * Math.Asin(Math.Min(1, Math.Sqrt(h1)));
    return R * h2;
}

public enum DistanceUnit { Miles, Kilometers };

var Offices = GetMyOfficeList();
for(int i = 0; i< Offices.Count; i++)
{
    Offices[i].Distance = HaversineDistance(
                            coord,
                            new LatLng(Offices[i].Lat, Offices[i].Lng),
                            DistanceUnit.Miles);
}

var closestOffice = Offices.OrderBy(x => x.Distance).Take(1).Single();

 

 

Tổng hợp các Mã nguồn mở .Net

Danh sách các open source cho anh em tham khảo mọi người biết cái gì mới thì bổ sung nhá 

Form MVC https://github.com/YodasMyDad/mvcforum

BlogEngine.NET http://blogengine.codeplex.com/releases

nopCommerce https://github.com/nopSolutions/nopCommerce

Đóng góp của bạn Nguyễn Xuân Thanh

 - DotnetNuke - Portal khá nhiều các đơn vị và cơ quan sử dụng http://www.dnnsoftware.com/ 

- Umbraco - CMS gần giống với khóa học https://umbraco.com

- MRCMS -  khó sài -https://www.mrcms.com/

Đóng góp của bạn Kiet Tuan Le

Đây là trang web có rất nhiều mã nguồn

Mọi người tham khảo nhe : https://webgallery.microsoft.com/gallery

Chia sẽ anh em hàm validate mình viết

Chia sẽ anh em hàm validate mình viết cái này được cái  cái này gọn nhẹ sài được cho div không cần gắn vào form, có thể validate những nhóm đối tượng tách biệt nhau, theo class, id , attributes....

Để xử dụng cần gán thuộc tính required vào và các loại class int, date, datetim, dec , email..

var ThuY = {};
ThuY.Form = function (formId) {
    this.hasError = false;
    this.$element = $(formId);

    this.focusError = function () {
        var $input = this.$element.find(".has-error:first :input");
        if ($input.length === 0) return;
        $("html, body").animate({ scrollTop: $input.offset().top - 100 }, 250);
        $input.focus();
    };
     function getValue($el) {
        return $el.is('[type="checkbox"]')
            ? $el.prop("checked")
            : $el.is('[type="radio"]') ? !!$('[name="' + $el.attr("name") + '"]:checked').length : $el.val();
    }
    this.getError = function () {
        var formError = {};

        this.$element.find('input[required],textarea[required],select[required]').each(function (i, requiredField) {
            var $el = $(requiredField);
            var $type = $el.attr('type');

            var $message = $el.attr('reqired-message');
            if (isNotSet($message)) {
                $message = "Giá trị này phải nhập";
            }

            var $maxLength = $el.attr('data-max');
            var $minLength = $el.attr('data-min');
            var $pattern = $el.attr('data-pattern');
            var $value = getValue($el);

            if ($el.hasClass('int')) {
                $value = $value.replace(/[^\d\.\-]/g, "");
                if ($value === '') {
                    formError[$el.attr('name')] = $message;
                } else if (typeof n == 'number' && /^-?\d+$/.test($value) === false) {
                    formError[$el.attr('name')] = "Vui lòng nhập vào chuỗi số";
                } else if (isSet($minLength)) {
                    if (parseInt($value) < $minLength) {
                        formError[$el.attr('name')] = "Giá trị nhập vào phải lớn hơn " + $minLength;
                    }
                } else if (isSet($maxLength)) {
                    if (parseInt($value) > $maxLength) {
                        formError[$el.attr('name')] = "Giá trị nhập vào phải nhỏ hơn hơn " + $maxLength;
                    }
                }
            } else if ($el.hasClass('dec')) {
                $value = $value.replace(/[^\d\.\-]/g, "");
                if ($value === '') {
                    formError[$el.attr('name')] = $message;
                } else if (/^\d+.?\d*$/.test($value) === false) {
                    formError[$el.attr('name')] = "Vui lòng nhập vào chuỗi số";
                } else if (isSet($minLength)) {
                    if (parseFloat($value) < $minLength) {
                        formError[$el.attr('name')] = "Giá trị nhập vào phải lớn hơn " + $minLength;
                    }
                } else if (isSet($maxLength)) {
                    if (parseFloat($value) > $maxLength) {
                        formError[$el.attr('name')] = "Giá trị nhập vào phải nhỏ hơn hơn " + $maxLength;
                    }
                }

            } else if ($el.hasClass('email') || $type === 'email') {
                if ($value === '') {
                    formError[$el.attr('name')] = $message;
                } else if (/^([a-zA-Z0-9_\-\.]+)@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.)|(([a-zA-Z0-9\-]+\.)+))([a-zA-Z]{2,4}|[0-9]{1,3})(\]?)$/.test($value) === false) {
                    formError[$el.attr('name')] = "Email không đúng định dạng";
                }

            } else if ($el.hasClass('url') || $type === 'url') {

                if ($value === '') {
                    formError[$el.attr('name')] = $message;
                } else if (/^(?:(?:(?:https?|ftp):)?\/\/)(?:\S+(?::\S*)?@)?(?:(?!(?:10|127)(?:\.\d{1,3}){3})(?!(?:169\.254|192\.168)(?:\.\d{1,3}){2})(?!172\.(?:1[6-9]|2\d|3[0-1])(?:\.\d{1,3}){2})(?:[1-9]\d?|1\d\d|2[01]\d|22[0-3])(?:\.(?:1?\d{1,2}|2[0-4]\d|25[0-5])){2}(?:\.(?:[1-9]\d?|1\d\d|2[0-4]\d|25[0-4]))|(?:(?:[a-z\u00a1-\uffff0-9]-*)*[a-z\u00a1-\uffff0-9]+)(?:\.(?:[a-z\u00a1-\uffff0-9]-*)*[a-z\u00a1-\uffff0-9]+)*(?:\.(?:[a-z\u00a1-\uffff]{2,})).?)(?::\d{2,5})?(?:[/?#]\S*)?$/i.test($value) === false) {
                    formError[$el.attr('name')] = "Website không đúng định dạng";
                }
            } else if ($el.hasClass('date')) {

                if ($value === '') {
                    formError[$el.attr('name')] = $message;
                } else if (/^(\d{2})[\/](\d{2})[\/](\d{4})$/.test($value) === false) {
                    //Check date 99/99/9999
                    formError[$el.attr('name')] = "Ngày tháng không đúng định dạng";
                }
            } else if ($el.hasClass('time')) {

                if ($value === '') {
                    formError[$el.attr('name')] = $message;
                    //Check time 99:99
                } else if (/([01]\d|2[0-3]):([0-5]\d)/.test($value) === false) {
                    formError[$el.attr('name')] = "Thời gian không đúng định dạng";
                }
            } else if ($el.hasClass('datetime')) {

                if ($value === '') {
                    formError[$el.attr('name')] = $message;
                } else if (/^(\d{2})\/(\d{2})\/(\d{4}) (\d{2}):(\d{2})$/.test($value) === false) {
                    //Check date time 99/99/9999 99:99
                    formError[$el.attr('name')] = "Thời gian không đúng định dạng";
                }
            } else if (isSet($pattern)) {

                if ($pattern.test($value) === false) {
                    formError[$el.attr('name')] = "Giá trị nhập vào không đúng định dạng";
                }
            } else {
                if ($value === '') {
                    formError[$el.attr('name')] = $message;
                } else if (isSet($minLength)) {
                    if ($el.val().length < $minLength) {
                        formError[$el.attr('name')] = "Giá trị nhập vào phải có số ký tự lớn hơn " + $minLength;
                    }
                } else if (isSet($maxLength)) {
                    if ($el.val().length > $maxLength) {
                        formError[$el.attr('name')] = "Giá trị nhập vào phải có số ký tự nhỏ hơn " + $maxLength;
                    }
                }
            }
            $el.bind('change', function () {
                formError[$(this).attr('name')] = null;
            });


        });

        if (!$.isEmptyObject(formError)) { this.hasError = true; }
        return formError;

    }
    this.isFloat = function (val) {
        var floatRegex = /^-?\d+(?:[.,]\d*?)?$/;
        if (!floatRegex.test(val)) return false;
        val = parseFloat(val);
        if (isNaN(val)) return false;
        return true;
    }

    this.isInt = function (val) {
        var intRegex = /^-?\d+$/;
        if (!intRegex.test(val))return false;
        var intVal = parseInt(val, 10);
        return parseFloat(val) === intVal && !isNaN(intVal);
    }
    this.resetForm = function () {
        this.$element.find("input, textarea, select").val("");
    }

    this.isEmpty = function (value, allowEmptyString) {
        function countProperty(obj) {
            var count = 0;
            for (var k in obj)
                obj.hasOwnProperty(k) && ++count;
            return count;
        }

        return value === false ||
            null === value ||
            isNaN(value) === false && 0 === parseInt(value, 10) ||
            "null" === value ||
            void 0 === value ||
            "undefined" === value ||
            (allowEmptyString ? false : "" === value) ||
            "object" == typeof value && 0 === countProperty(value) ||
            "object" == typeof value && 1 === countProperty(value) && "" === value[0] ||
            value instanceof jQuery && 0 === value.length;
    }
    this.loadItem = function () {
        var $item = {};
        this.$element.find('input,textarea,select')
            .each(function (i, item) {
                $item[$(item).attr('name')] = getValue($(item));
            });

        return $item;
    }
    this.item =  this.loadItem();
}

để xử dụng trong controller mình làm như sau

var form = new ThuY.Form("#formAddKhach");
$scope.formErrorAddKhach = form.getError();
if (form.hasError) {
    form.focusError();
    return;
}

html

<div class="col-md-3">
    <div class="form-group" data-ng-class="{'has-error' : formAddKhach.Ten.$invalid && formAddKhach.Ten.$dirty || formErrorAddKhach.Ten}">
        <label class="control-label" for="Ten">{{L('Ten')}} <span class="require">*</span></label>
        <div class="">
            <input class="form-control" id="Ten" name="Ten" ng-model="itemAddKhach.Ten" required reqired-message="Tên bắt buộc nhập." />
            <span class="help-block" ng-show="formAddKhach.Ten.$invalid  && formAddKhach.Ten.$dirty">Nhập {{L('Ten')}}</span>
            <span class="help-block" ng-if="formErrorAddKhach.Ten">{{formErrorAddKhach.Ten}}</span>
        </div>
    </div>
</div>

 

Một số phương thức của mảng trong Javascript

Để viết các ứng dụng với javascript thì việc vận dụng mảng là một điều hết sức cần thiết. Javascript cũng như các ngôn ngữ lập trình khác cũng có mảng và cách thức làm việc của mảng trong Javascript cũng tương tự, vấn đề cần quan tâm là các chức năng thao tác với mảng thì mỗi một ngôn ngữ lập trình đều viết sẵn một số hàm hoặc phương thức để thao tác, ý nghĩa của các hàm thì giống nhau chỉ khác ở cách khai báo và cách gọi tên hàm của từng ngôn ngữ.

Trong bài viết này chúng ta sẽ tìm hiểu một số phương thức thường được dùng để thao tác với các phần tử mảng trong Javascript.

Trong PHP bạn có thể khai báo mảng bằng rất nhiều cách ngắn gọn trong đó có một cách rất đơn giản là sử dụng dấu ngoặc vuông "[]" khi nào cần sử dụng mảng mà không cần phải khai báo trước, trong dấu ngoặc vuông có thể bỏ trống và PHP sẽ tự gán key cho mảng đó. Trong Javascript thì bạn không thể khai báo theo cách ngằn gọn giống PHP như trên mà cần phải khai báo mảng trước sau đó mới có thể sử dụng. Cú pháp khai báo mảng của Javascript là new array("phần tử","phần tử",..."").

Một điều nhấn mạnh rằng mảng trong Javascript là một đối tượng, sau đây sẽ là một số phương thức cần thiết để bạn thao tác với mảng:

  1. push("phần tử", "phần tử") -> Phương thức sẽ thêm phần tử vào cuối mảng
  2. unshift("phần tử", "phần tử") -> Phương thức sẽ thêm phần tử vào đầu mảng
  3. pop() ->Phương thức sẽ xóa phần tử cuối trong mảng
  4. shift() ->Phương thức sẽ xóa phần tử đầu trong mảng
  5. sort() ->Phương thức sẽ sắp các phần tử mảng theo giá trị tăng dần đồng thời gán lại key theo thứ tự tăng dần, chú ý phương thức chỉ có tác dụng với mảng có key liên tiếp bắt đầu từ 0
  6. concat() ->Phương thức kết hợp hai mảng thành một
  7. slice(ví trí bắt đầu, vị trí kết thúc) ->Phương thức tách ra một mảng con
  8. join() ->Phương thức tạo một chuỗi từ một mảng, đối số là chuỗi nối các giá trị của phần tử trong mảng
  9. reverse() ->Đảo ngược các vị trí phần từ trong mảng đồng thời xắp lại key

Ngoài ra chúng ta còn có một số các phương thức hữu dụng khác như every(), some(), filter(), forEach(), map() tuy nhiên chúng lại không được hổ trợ bởi các trình duyệt cũ như IE7.
Có một phương thức vô cùng mạnh mẽ khác trong javascript đó là phương thức splice(), nó có thể thay thế cho các phương thức như pop(), push(),shift(), unshift() ở trên:

  1. splice(vị trí bắt đầu, số lượng) ->Phương thức sẽ xóa một số phần tử tại vị trí bất kỳ trong mảng
  2. splice(vị trí bắt đầu, số lượng, "phẩn tử mới", "phần tử mới",""...) ->Khi thêm đối số vào phương thức nó sẽ thay thế các phần tử mới vào các phần tử đã xóa.

Chúng ta có thể thấy việc thao tác với các phần tử mảng trong Javascript cũng không có gì khó khăn điều quan trọng là chúng ta biết vận dụng các phương thức của chúng khi cần thiết. Bài viết này tôi chỉ mang hình thức giời thiệu, nếu bạn muốn thực sự làm việc với Javascript thì chí ít bạn cũng phải biết chút ít kiến thức về lập trình căn bản, bạn có thể tự làm ví dụ để hiểu rõ hơn nếu bạn chưa thực sự hiểu về nó.

jQuery basic: CSS Selectors

jQuery thực sự mạnh mẽ thật đúng với slogan "write less, do more", nó là một thư viện JavaScript rất giễ ràng sử dụng nó giúp các nhà thiết kế và phát triển web thêm các các phần tử có sự tương tác và có tính năng động về phía người dùng. Nếu trước kia bạn viết JavaScript mà không sử dụng thư viện thì sẽ rất dài vì bạn phải tự xây dựng thêm các hàm để chọn rồi sử lý phần tử bây giờ mọi thứ trở nên đơn giản và ngắn gọn như bạn viết CSS vậy. Bài viết này sẽ giới thiệu về các biểu thức chọn trong jQuery theo dạng CSS selector.

Element

Để chọn theo tên thẻ sử dụng cú pháp $('tên thẻ')

ID: #myid

Chọn theo tên id của phần tử sử dụng cú pháp $('tên id')

Class: .myclass

Chọn theo tên class của phần tử sử dụng cú pháp $('.tên class'). Có một điều nên chú ý rằng trong cấu trúc hồ sơ của bạn thì class thường được dùng cho nhiều phần tử nên kết quả biểu thức chọn này thường trả về một mảng phần tử.

Descendant: E F

Chọn theo con cháu ví dụ chọn phần tử img là hậu duệ của phần tử a sẽ có cú pháp $('a img')

Child: E > F

Chọn theo thẻ con trực tiếp cú pháp $('tên thẻ > tên thẻ'). Phương pháp chon theo CSS này được hổ trợ trên hầu hết các trình duyệt hiện đại và không hổ trợ trên trình duyệt IE từ phiên bản 6 về trước

Adjacent Sibling: E + F

Chọn những thẻ có cùng phần tử cha và nằm kế nhau tức chúng là anh em của nhau, cú pháp $('tên thẻ + tên thẻ')

General Sibling: E ~ F

Chọn những phần tử F cùng cấp với phần tử E, cú pháp $('tên thẻ ~ tên thẻ')

Multiple Elements: E,F,G

Chọn nhiều phần tử cùng lúc, cú pháp $('tên thẻ, tên thẻ,...')

Nth Child (:nth-child(n))

Chọn phần tử con theo thứ tự chỉ mục n, ở đây nth-child(n) sẽ đánh số từ 1 và đánh chỉ mục với tất cả các thẻ con, trong khi đó nth(n) sẽ đánh số từ 0 và chỉ đánh chỉ mục theo phần tử bạn chọn. Ngoài ra bạn có thể thay n bằng từ khóa even để chọn những phần tử con chẵn hoặc odd để chọn những phần tử con lẻ.

First Child (:first-child)

Chọn phần tử con đầu tiên, cú pháp $('tên thẻ:first-child')

Last Child (:last-child)

Chọn phần tử con cuối cùng, cú pháp $('tên thẻ:last-child')

Only Child :only-child

Chọn tất cả những phần tử chỉ là con, cú pháp $('tên thẻ:only-child')

Not :not(s)

Chọn theo dạng phủ định. Ví dụ

  • $('li:not(.myclass)') Chọn những phần tử li nào không có class tên myclass
  • $('li:not(:last-child)') Chọn những phần tử  li nào không phải là phần tử con cuối cùng

Empty :empty

Chọn những phần tử nào rỗng tức là nó không có con cháu, cú pháp $('phần tử:empty') hoặc $(':empty')

Universal: *

Dấu * sử dụng trong thẻ chọn đại diện cho tất cả các phần tử

Trong những bài viết tiếp theo sẽ giới thiệu về những phương pháp chọn phần tử tiếp theo.

Tham khảo (jQuery Reference Guide and docs.jquery.com)